Musthafa
Musthafa

Reputation: 632

Render method called twice with componentDidMount - React native

I'm fetching some data from the firebase realtime database. I have created a state in the constructor and initialised as an empty array. Later in the componentDidUpdate method, I have updated the state with setState method. The issue is the render method called twice in the component and data is getting multiplied each time.

this.state = {
            values: [],
   }

componentDidMount = () => {
        firebase.database().ref('Table').once('value', (data) => {
            var input = data.val();
            this.setState({ values: input })
        })
    }

And the render method:

var val = []; //global variable declared before class declaration

render() {
    {
        this.state.values.map(item => {
            val.push(
                <List>
                    <ListItem>
                        <Text>{item["value"]}</Text>
                    </ListItem>
                </List>
                )
        })  
    }
    return(
        <View>
            {val}
        </View>
    )
}

And the list item is keep getting multiplied each time when the component renders. I have checked the doc but couldn't get a proper solution. https://reactjs.org/docs/react-component.html#componentdidmount

Upvotes: 0

Views: 285

Answers (2)

Mahdi N
Mahdi N

Reputation: 2178

I didn't understand well the val variable but this code should work for you:

mapValues = list => list.map((item, index) => (
  <List key={index}>
    <ListItem>
      <Text>{item.value}</Text>
    </ListItem>
  </List>
));

render() {
  return (
    <View>
      {this.mapValues(this.state.values)}
    </View>
  );
}

Upvotes: 0

Thomas
Thomas

Reputation: 12637

Where is val defined?

Okay. That I have defined a global var. Declared it as an array before the class declaration

That's where your duplication comes from.

Better do it this way:

render() {
    const val = this.state.values.map((item, index) => (
        <List key={index}>
            <ListItem>
                <Text>{item.value}</Text>
            </ListItem>
        </List>
    ));

    return <View>{val}</View>;
}

Upvotes: 1

Related Questions