0

I created a Checklist component in which all checks are by default FALSE, as I click to check any of one I set Component State and send State to the Store reducer. And After doing so the problem arrives. The problem is that:- I want Store data in another Component(MyComp) with the help of mapStateToProps. But componentWillReceiveProps is not triggered as I changed Checklist data.

I searched for this problem and found that React is not able to Deep checks the upcoming props. I tried with single toggle(true/false) props and it works for me.

This is MyComp.js which is using Store State(toggle, platforms) as a props

class MyComp extends React.Component{

componentWillReceiveProps=(nextProps)=>{
      console.log(nextProps);
// this function is running only when the toggle is changing but not running when I change CheckList State.
}

 render()(<div></div>);
}
const mapStateToProps = (State) => {
        return {
 platforms:State.configuration.platforms!==undefined?State.configuration.platforms:[],//<-- Not triggered componentWillReceiveProps

toggle:State.toggle //<-- it triggered componentWillReceiveProps       
        }
    }
export default connect(mapStateToProps)(FeatureEvents);

...

This is props which are coming from the Store. In this only selected property is changing.

platforms props : [
{
background: "https:image/file/59fd566788f3ac79a46ef20d/Android.png",
description: "Operating system used by various brands",
icon: "https://duj87royd3ze0.cloudfront.net/uploads/image/android.png",
id: "587f1e2f14c49f4aeb4d79d4",
price_multiplier: 1.5,
selected: true,
title: "Android",
week_multiplier: 1.1,
},
{..},
...
{..}
]

EXPECTED: As I changed "selected" property value (true/false) by checked or unchecked in the CheckList, I want to trigger componentWillReceiveProps in MyComp.

CURRENT STATUS: React not Triggering componentWillReceiveProps. Because React is not able to identify deep check.

How can I code so that React will start to deep check upcoming props?

B4BIPIN
  • 353
  • 2
  • 11
  • You need to write your own checker function for deeply nested datasets. You'd need a nested loop scenario here. Also, it seems like you are using a pretty old version of `react` try to update as some methods such as `componentWillReceiveProps` are considered legacy and will be deprecated soon! – ShocKwav3_ Jul 11 '19 at 10:04
  • No, @ShocKwav3_, React version is "react": "^16.8.5", and from where I should write that code? – B4BIPIN Jul 11 '19 at 10:35
  • Take a look at this: https://reactjs.org/docs/react-component.html#mounting – ShocKwav3_ Jul 11 '19 at 10:38
  • You need to write that code in the component lifecycle function which triggers when there is update/newprop, for your code it is `componentWillReceiveProps` but I suggest you to use `componentDidUpdate`: https://reactjs.org/docs/react-component.html#componentdidupdate or `getDerivedStateFromProps`: https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops depending on your choice/use – ShocKwav3_ Jul 11 '19 at 10:41
  • If you are adding to the state and then showing the data taken from the state then use one of those two methods. Other wise if you have a controlled component then you simply have to do nothing. Although react will trigger a rerender if the the props in this case changes references/address in the memory but holding same data. In that case use can use `shouldComponentUpdate` where you implement your checker function to compare your newprops and current props if it has actually changed and decide to update the component or not. https://reactjs.org/docs/react-component.html#shouldcomponentupdate – ShocKwav3_ Jul 11 '19 at 10:47
  • You can trigger by ensuring a new object is created every-time. e.g. `return { something: myArray ? [...myArray] : [] }` – Kunukn Jul 11 '19 at 10:50
  • To understand this scenario more you should find out how JS operate comparism for bith primitive and non-primitive data. – ShocKwav3_ Jul 11 '19 at 10:51
  • @Kunukn that'd result in an unneccessary rerender if the values are same – ShocKwav3_ Jul 11 '19 at 10:53
  • @ShocKwav3_ That is correct. I would then probably look at where `State.configuration.platforms` is updated and ensure that is a new object if the structure has changed and simply do this in mapStateToProps `return { platforms:State.configuration.platforms }` – Kunukn Jul 11 '19 at 11:42
  • You could do that sure, but I'd suggest use caching in the container before returning the value or put the checker in the component. But hey it varies on your component if it is controlled or not. – ShocKwav3_ Jul 11 '19 at 11:49
  • Thanks, everyone. I solved my issue. The problem is that the state was updating at same reference, so **React** was not able to differentiate between prevProps and nextProps. What I did is `var tempArray = JSON.parse(JSON.stringify(mainArray));` – B4BIPIN Jul 12 '19 at 07:37
  • @B4BIPIN good that you have found a solution. That specific solution may backfire to you if your JSON has cyclic dependencies. I, myself, not very clear about how it works but this is something I came across recently but did not have time to explore on that. Happy coding! – ShocKwav3_ Jul 12 '19 at 08:35

0 Answers0