Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React memo always get the same results on prevparams and next params #16643

Closed
andrestamayoglobant opened this issue Sep 3, 2019 · 3 comments

Comments

@andrestamayoglobant
Copy link

andrestamayoglobant commented Sep 3, 2019

Hello i'm trying to implement React memo on my project to especify when i want to update my component. But i realize that i'm always receiving the same values on prevProps, and currentProps so i cant make any validation.

Now im making it in this way:

const Task =(props)=>{
//some code here...
}
function areEqual(prevProps, currentProps) {
    console.log("1 ",prevProps.task.stateCheckbox);
    console.log("2 ",currentProps.task.stateCheckbox);
    return false;
}
export default React.memo(Task, areEqual);

The field I'm editing it's in the parent component and it made it in this way :

  handleStateTask=(position)=>{

    this.setState((prevState)=>{
       console.log(prevState.taskList[0]);
      const arrTemp=[...prevState.taskList];
      arrTemp[position].stateCheckbox=!arrTemp[position].stateCheckbox;
      return{
        taskList:arrTemp
      }
    })
  }

it works well and update the field on it's specify position. My problem its that on React memo it cant detect the previous state.

Can anybody give me some ideas about what am i making wrong..

thanks..

@threepointone
Copy link
Contributor

So, this line makes a shallow copy of the array taskList:

const arrTemp=[...prevState.taskList];

This means that while the array instances are different, the actual items are still shared among the 2 arrays.

Then, this line:

arrTemp[position].stateCheckbox=!arrTemp[position].stateCheckbox;

mutates the value of the item. As mentioned, because it's shared, it will change the value in both the arrays. Hence, the failure to detect the change in the memo comparator.

A quick attempt at a workaround:

const arrTemp=[...prevState.taskList];
arrTemp.splice(position, 1, {...arrTemp[position], stateCheckbox: !arrTemp[position].stateCheckbox )

I haven't tested it, but note how it creates a whole new item to replace the item that's being changed.

This is more of a usage question, consider using one of community resources in the future https://reactjs.org/community/support.html

@andrestamayoglobant
Copy link
Author

thanks for your help, it works!

@kaialsh705
Copy link

the same problem, please help me.
here is my code

this function call in parent.
decision_bookmark = (operation, index, id) => {
if (operation === 'delete') {
this.setState({
extraData: !this.state.extraData,
});
if (this.state.matchActive) {
lodash.filter(this.state.decisions, ['id', id])[0].is_saved = false;
}
} else {
this.setState({
extraData: !this.state.extraData,
});
lodash.filter(this.state.decisions, ['id', id])[0].is_saved = true;
}
};

this is my child component
function Child(){
//return
}
function areEqual(prevProps, nextProps) {
// console.log('prevProps', prevProps);
// console.log('nextProps', nextProps);
}
export default React.memo(Child, areEqual);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants