react-native: Memory when using conditional render - react-native

For example I have View and in this View we have another View2 which is rendered conditionally. So if I will show and hide this View2 1000 times will it affect memory?
<View>
{condtion && <View><Text>2<Text><View>
<View>

First react and react-native has a different concept of how classes react to each other. here is more details about that
Also, you can use redux or other statement manager library like mobix flux and another alternative solution you can use props you code in main render function you can create/write a component like this
<ChangeTextComponent condition={you_condition}/>
When change you condition only render ChangeTextComponent component render.
class AnotherPage_Test extends Component {
render() {
return (
<View>
<ChangeTextComponent condition={you_condition}/>
</View>
)
}
}

Related

Programmatically Closing React Native Swipe List View

I'm using react-native-swipe-list-view (https://github.com/jemise111/react-native-swipe-list-view) in my React Native app and I'm trying to close rows programmatically.
Once the user swipes to the right or left and clicks the button there, I call a function to make API calls and handle a few things. This is where I also try to close the row programmatically. This is working ONLY for the last item in the list. Anything above it, the row stays open.
I do hit my handleClickUpdateItemStatus() function and the API call works fine but as I said, only the last item in the list will close. Anything above that one stays open even though all the other code in the function work fine.
My code looks like this:
class MyComponent extends Component {
constructor(props) {
super(props);
this.handleClickUpdateItemStatus = this.handleClickUpdateItemStatus.bind(this);
}
handleClickUpdateItemStatus(itemId, value) {
this._swipeListView.safeCloseOpenRow();
// Call my API to update item status
}
render() {
return(
<Container>
<SwipeListView
ref={ref => this._swipeListView = ref}
data={this.props.items}
... // Omitted for brevity />
</Container>
);
}
}
Any idea what's causing this?

Simplified style change onPress React Native

The following is a first attempt at learning to simply change the style of an element onPress in react native. Being well versed in web languages I am finding it difficult as it is not as straight forward.
For reasons as yet unknown, the element requires two clicks in order to execute.
export class NavTabItem extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false
}
this.NavTabAction = this.NavTabAction.bind(this)
}
NavTabAction = (elem) => {
elem.setState({active: !elem.state.active})
}
render() {
return (
<TouchableOpacity
style={this.state.active ? styles.NavTabItemSelected : styles.NavTabItem}
onPress={()=> {
this.NavTabAction(this)
}}>
<View style={styles.NavTabIcon} />
<Text style={styles.NavTabLabel}>{this.props.children}</Text>
</TouchableOpacity>
);
}
}
Other issues:
I also have not worked out how a means of setting the active state to false for other elements under the parent on click.
Additionally, Is there a simple way to affect the style of child elements like with the web. At the moment I cannot see a means of a parent style affecting a child element through selectors like you can with CSS
eg. a stylesheet that read NavTabItemSelected Text :{ // active style for <Text> }
Instead of calling elem.setState or elem.state, it should be this.setState and elem.state.
NavTabAction = (elem) => {
this.setState(prev => ({...prev, active: !prev.active}))
}
And instead of passing this in the onPress, you should just pass the function's reference.
onPress={this.NavTabAction}>
You should also remove this line because you are using arrow function
// no need to bind when using arrow functions
this.NavTabAction = this.NavTabAction.bind(this)
Additionally, Is there a simple way to affect the style of child elements like with the web
You could check styled-component, but I think that feature don't exists yet for react native. What you should do is pass props down to child components.
Thanks to everyone for their help with this and sorting out some other bits and pieces with the code.
The issue in question however was that the style was changing on the second click. A few hours later and I have a cause and a solution for anyone suffering from this. Should any of the far more experienced people who have answered this question believe this answer is incorrect or they have a better one, please post it but for now here is the only way I have found to fix it.
The cause:
Using setState was correctly re rendering the variables. This could both be seen in the console via console.log() and directly outputted in the render making them visible.
However, no matter what was tried, this did not update the style. Whether it was a style name from the Stylesheet or inline styles, they would update on the second click rather than the first but still to the parameters of the first. So if the first click should make a button turn from red to green, it would not do so even though the new state had rendered. However if a subsequent click should have turned the button back to red then the button would now go green (like it should have for the first click). It would then go red on the third click seemingly always one step behind the status passed to it.
Solution
To fix this, take the style off the the primary element (forgive terminology, someone edit), in my case, the TouchableOpacity element. Add in a child View element and place the styles on that View element instead along with the ternary operator and wallah.
It seems any change to status on the effective master element or container if you prefer, only takes affect after another render, not that contained in setStatus.
Final code:
export class NavTabItem extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false
}
}
NavTabAction = () => {
this.setState({active: !this.state.active})
}
render() {
this.state.active == true ? console.log("selected") : console.log("unselected")
return (
<TouchableOpacity onPress={this.NavTabAction}>
// added View containing style and ternary operator
<View style={this.state.active == true ? styles.NavTabItemSelected : styles.NavTabItem}>
<View style={styles.NavTabIcon} />
<TextCap11 style={styles.NavTabLabel}>{this.props.children}</TextCap11>
</View>
// End added view
</TouchableOpacity>
);
}
}

SectionList re-renders everything unexpectedly

I'm new to React-Native, currently working a project that displays photos and its related information. The project uses the standard SectionList(RN 0.55).
The problem I have is that each time I add a photo, all the subcomponent in the list will be re-rendered. And I've noticed a significant slow down when the list grows to 50 something.
I have the following setup:
I have a redux store which contains Data(basically a wrapper around photo information), each time user does some action, the Data will be copied, modified, then reassigned back to redux store.
Then I have a class like following to render SectionList
class PhotoList extends PureComponent {
render() {
<SectionList
sections={deriveData(this.props.data)}
extraData={this.state}
renderItem={this.onRenderItem}
>
}
onRenderItem(item) {
return <View>
// two nested level components to hold information
</View>
}
driveData(data) {
// do a lot of data transformation and calculate derived value
return derivedData;
}
}
// data is redux connected
My primary confusing point is that, when SectionList takes in section in my case, the data(as a whole) is already a new copy and is modified(since a new photo is added), so it causes SectionList to re-renders everything?
I want SectionList to only additionally render the photo I just added, any suggestions?
Can you change the data ("data transformation and calculate derived value") at action and update that on redux 'data'. Then change like the following.
class PhotoList extends PureComponent {
render() {
<SectionList
sections={this.props.data} // Directly call data
extraData={this.props.data}
renderItem={this.onRenderItem}
>
}
onRenderItem(item) {
return <View>
// two nested level components to hold information
</View>
}
}
If you use redux then you have to handle data updating on redux. Then only the result will get.

dynamic text change in react-native

Hi I am looking for the solution to change text dynamically.
I am writing code to show processing results on screen.
After some googling, I found there is a code to update text dynamically as follows.
But I would like to update text without any internal event. I want to change text from outside of the class. But I don't know how to implement it as I am a javascript and react-native beginner. There are other classes to process some functions so that I need to show the updated results using Results class which is an another component of the screen.
How can I deliver 'result' to Results class and how to update it dynamically and automatically?
class Results extends Component {
constructor() {
super()
this.state = {
log: 'Processing results'
}
}
updateText = (result) => {
this.setState({log: result})
}
render() {
return (
<View>
<Text onPress = {this.updateText}>
{this.state.log}
</Text>
</View>
)
}
}
This sounds to me that props can solve your problem.
Basically when you try to render Results class, pass along the value as a prop like below:
<Results dynamicText='HI' />
Then, from your Results class, access this external value via this.props.dynamicText as below
class Results extends Component {
render() {
return (
<View>
<Text>
{this.props.dynamicText}
</Text>
</View>
)
}
}
In addition to what #Issac answered, you can also hook up your current class to Redux and dispatch actions from another class to force state changes.
React Native and ReactJS has a different concept of how classes react to each other. Most other languages use inheritance based interactions to affect changes in classes other than itself. React itself is more composition based where changing the value/state/variable of one class requires either a state change or a prop change. The caveat to that us using Redux, which utilizes an overarching Store where any component that's connected to it can pull values or dispatch actions to change values.

Rendering Components runtime during the navigation in react-native

I want to display a component(say, a View or Text component) in my current screen only if I return back to this screen from some other screen.
For e.g, say I am at the Home.js where I am displaying the view components. The count of this view components depends upon the number of times one goes(or visits) the Break.js screen. Like If i have visited the Break.js screen thrice, then there should be 3 View components available at the Home.js screen.
I am a beginner in React-Native, so don't have any idea how to implement this....I have gone through the similar query like
Dynamically rendering components - React Native and
React Native View Render
but couldn't understand anything. Pls help as I have nothing to show what I have tried so far.....
Below is one way of updating your component, where you update the viewCount before navigating to the other screen. This works only if the previous screen exists in the memory after navigation like in the cases of stack navigators. This is a basic idea which u can modify for your use case.
class HomeScreen extends Component {
onNavigate() {
this.updateViewCount();
// ... navigate to BreakScreen
}
updateViewCount() {
this.setState({numOfViews: this.state.numOfViews + 1});
}
render() {
// Create an array and push your elements based on count
// this.state.numOfViews manages the count
let views = [];
for(let i = 0; i <= this.state.numOfViews; i++) {
views.push(<SomeComponent />);
}
// Render your custom views
return(
<View>
{views}
<Button onPress={() => this.onNavigate()} />
</View>
);
}
}