Home > Enterprise >  useState with arrays not rerendering
useState with arrays not rerendering

Time:09-26

I am facing issue while using useState hook with array. I checked various resources on stackoverflow, but could not fix it.

my basic code snippet looks like :

const [users, setUsers] = useState([]);

  function addNewContact(user) {
    const newUsers = [...users,user];
    console.log(newUsers);
    setUsers(newUsers);
  }
<CardContainer users={users}></CardContainer>
class CardContainer extends Component {

    constructor(props) {
        super(props);
        console.log("this -> ");
        console.log(this.props.users);
        this.state = {
            users: this.props.users
        }
    }

    render() {
        //console.log(this.state.users)
        return (
            <div class="row row-cols-1 row-cols-md-2 g-4">
                {
                    this.state.users.map(user => {
                        return <Card id={user.phone} title={user.name} email={user.email} phone={user.phone}></Card>
                    })
                }
            </div>
        )
    }

}

export default CardContainer;

I am able to see updated array in the console, but the component using it is not rendering again. Can anyone please help me on this.

CodePudding user response:

The issue is due to you're storing the prop in the state of the child component, which is assigned on component initialization and component initialization/constructor only run one, until its remounted. After that, whenever, the state changes in the parent component, the child component is not re-rendering, because it uses its own state for map.

This below code only runs once on the component initialization.

this.state = {
   users: this.props.users
}

In the child component, you can directly use the props and the child component will always re-render on change in the parent component. Instead of this.state.users.map you can directly map the array from props like this this.props.users.map. This way,the component will re-render on state change in the parent compoenent.

CodePudding user response:

As @Junaid said, constructor is only called once before component mounting. If you really need to set a separate state inside the child component, then you can use componentDidUpdate(prevProps) react life cycle method. Make sure to compare previous and current props in order to avoid infinite loop of re-rendering.

componentDidUpdate(prevProps) {
  if (this.props.users !== prevProps.users) {
    this.setState({ users: this.props.users });
  }
};
  • Related