How to check if prevProps and nextProps are the same in React?
Don't use componentWillReceiveProps -- this hook will be soon deprecated. componentDidUpdate is the correct hook for what you need.
The problem is that the comparison you're doing is a shallow comparison -- i.e. it doesn't compare the nested values in the respective arrays.
The basic idea is that you should loop over both arrays and compared individual nested values -- here's more information about that: How to compare arrays in JavaScript?
You could also use something like's lodash's isEqual method to perform a deep comparison between two arrays: https://lodash.com/docs/4.17.10#isEqual
Comparing prevProps and nextProps in a React.memo Component to prevent unnecessary re-rendering but it's acting funny
That was a good head-scratcher, but I think I found the issue.
When you create your callback modifyPlayer
you rightly pass playerDict
as a dependency, since the callback relies on having an "up to date" version of playerDict
before it can create a new version of playerDict
using the latest update event. But this also means that each time the the depencendy playerDict
changes (with every change event) you will get a new modifyPlayer
-callback function.
But the areEqual
function in the Player
-component (around line 29) says that the component should only update if any of the player
properties have changed (id, firstName or lastName), this means that the component never receives the updated callback-function, so it will try to update the the playerDict
using the "wrong" previous version of the data (because it has a previous version of the callback function).
Including a check for equality between prevProps.modifyPlayer
and nextProps.modifyPlayer
makes the code behave like expected again:
// in Player.js - around line 29
(prevProps, nextProps) => {
// Check to see if the data is the same
if (
prevProps.player.firstName === nextProps.player.firstName &&
prevProps.player.lastName === nextProps.player.lastName &&
prevProps.player.id === nextProps.player.id &&
prevProps.modifyPlayer === nextProps.modifyPlayer
) {
return true; // Return true if they ARE the same
} else {
return false; // Return false if they are NOT the same
}
}
Edit: Updated demo code here https://codesandbox.io/s/damp-surf-nu6tt
What is the best way to compare between the many prevProps and nextProps in Reactjs?
I want to update the child component if there is any update in the props.
This is what React does by default! You should work with its normal component updates rather than trying to fight against it and decide whether to update things yourself.
You can use getDerivedStateFromProps
for this, but there are probably better ways still, like just computing the vector directly in the render
method.
Here is an article with lots more detail: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
After updating props, this.props is always === nextProps / prevProps
===
will check if it's the same object. It seems that what you're doing is mutating the value that the boxes
property points to.
React.memo prevProps always different from nextProps even if props never changes
If you use ===
JS will make a reference comparison and what you need is a deep comparison. For do this you could use something like this => https://stackoverflow.com/a/38416465/8548193
or use lodash [https://lodash.com/docs/] to make it more easier;
with lodash it will be something like this:
const _ = require("lodash");
_.isEqual(prevProps, nextProps);
Why prevProps always the same to current props in componentDidUpdate?
It depends on how you change your state and person object in it.
See the example here, it works correctly.
The first state doesn't have any id, so you get an error. In case if you have some person id and then change the state to new data it's should be new object with a new reference
class Person extends React.PureComponent {
componentDidUpdate(prevProps) {
if (prevProps.person !== null && (prevProps.person.id !== this.props.person.id)) {
console.log('it works');
}
}
render() {
const { person } = this.props;
return (
<>
{person && person.name}
</>
);
}
}
class A extends React.PureComponent {
constructor() {
super();
this.state = {
person: null
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
person: {
id: 0,
age: 20,
name: 'John'
}
})
}, 1000);
}
render() {
const { person } = this.state;
return (
<>
<Person person={person} />
</>
);
}
}
ReactDOM.render(
<A />,
document.getElementById('root')
);
Comparing PrevProps in componentDidUpdate
Hi :) as noted in my comment, the issue is in your App.js file - you are mutating an array. In other words, when you THINK you are creating a new array of selected countries to pass down, you are actually updating the original array, and so when you go to do a comparison you are comparing the two exact same arrays ALWAYS.
Try updating your App.js like so -
selectLocation = (id, type, lng, lat, polydata, name, clear = false) => {
//console.log(type); //console.log(lng); //console.log(lat); //console.log(polydata);
let selectedType = 'selected' + type; let previousState = [];
if (clear) { this.setState({ selectedCountries: [], selectedLocations: [], selectedServices: [], selectedPoints: [], mapCenter: [lng, lat], locationGeoCoords: [polydata] }) previousState.push(id);
} else {
previousState = [].concat(this.state[selectedType]); if (previousState.indexOf(id) === -1) { //push id previousState.push(id);
} else { //remove id var index = previousState.indexOf(id) previousState.splice(index, 1); } }
if (type === "Countries") {
this.setState({ selectedCountries: previousState, refreshData: true, }) } else if (type === "Locations") { this.setState({ selectedLocations: previousState, refreshData: true }) } else if (type === "Points") { this.setState({ selectedPoints: previousState, refreshData: true }) }
}
render() { return (
<component selectedCountries={this.state.selectedCountries} selectedLocations={this.state.selectedLocations} refreshData={this.state.refreshData} /> }}
Related Topics
If Check Box Checked Disable Other, If Unchecked Enable All in React
To Check If a String Is Alphanumeric in JavaScript
Get Count of True Values in Json With JavaScript
Electron - How to Add External Files
Why Does Prettier Not Format Code in VS Code
How to I Retrieve Last Part of Url and Use It in HTML
How to Change the State Correctly (Read-Only Error)
How to Change Background Color of a Row on Checkbox Selection
Prevent Particular Child Element from Firing Parent'S Mouseover Event in Jquery
Javascript Function (Input Date Bigger Than Today Date)
Connection Refused! Is Selenium Server Started
How to Detect If a Browser Is Blocking a Popup
Onchange Event Updates State With 1 Character Delay
Vuejs Accessing a Method from Another Method
How to Add Counter in Angular 6
415 (Unsupported Media Type) With Rest Post Request
Regex to Match Words With Hyphens And/Or Apostrophes
Removing Currency Symbol and Replacing Comma With Point Using Pure JavaScript