0

I read on the internet that it is a bad bad coding practice to perform the following:

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      someItem = props.someItem
    };
  }
}

However, if I had this scenario instead:

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      someItem = this.props.someItem
    };
  }
}

Test.propTypes = {
  someItem: PropTypes.array
};

function mapStateToProps(state, ownProps) {
  [...]
  return {
    someItem: someItem
  };
}

export default withRouter(connect(mapStateToProps)(Test));

Will there be an issue? Cannot find anywhere on the net that does not say that i cannot do that.

I am trying to ensure that everytime i navigate back to this component, the component is able to get the data from the Redux Store. I tried using componentWillReceiveProps(), but so far it only runs once and componentDidMount and componentWillMount does not accept setState.

Cheers.

AKJ
  • 519
  • 3
  • 18
  • Just use the props directly. Why do you want to copy that to state? Also componentWillReceiveProps is depreciated. – johnny peter Feb 20 '19 at 06:52
  • @johnnypeter i know, i am using React 15 that is why it is still available. As mentioned, if i rely on the componentWillReceiveProps() method, it will only run once. When i navigate away and return back to the page, it will not run and my local states will not be updated. – AKJ Feb 20 '19 at 06:57
  • there should be a single source of truth, either prop or state, you can assign prop to state in constructor if you mean to initialize the state with props on first mount and then leave it to the component – Rahul Yadav Feb 20 '19 at 07:07
  • Yes Rahul, but i read articles saying it is not good to initialize it to state. So i am confuse here – AKJ Feb 20 '19 at 07:08

1 Answers1

1

You should not save props in state unless and until you would want to modify it at a later point in time locally and update it after some action to the provider of props. In short you state must not be directly derivable from props at all points of time in your code.

Even though you use redux mapStateToProps to provide props to component, its still the same as coming from parent

class Test extends React.Component {
  render() {
      console.log(this.props.someItem);
  }
}

Test.propTypes = {
  someItem: PropTypes.array
};

function mapStateToProps(state, ownProps) {
  [...]
  return {
    someItem: someItem
  };
}

export default withRouter(connect(mapStateToProps)(Test));
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
  • I need to modify it some point later. Also, if you refer to https://stackoverflow.com/questions/54778492/redux-store-not-connected/54779273?noredirect=1#comment96338523_54779273 you will understand the context of my question. I cannot seem to ensure that my local state is geetting data from the store since componentWillReceiveProps only runs once. – AKJ Feb 20 '19 at 07:00
  • componentWillReceiveProps is not called once but on every render of parent and also on props change – Shubham Khatri Feb 20 '19 at 07:04
  • Also please check this question https://stackoverflow.com/questions/48139281/react-doesnt-reload-component-data-on-route-param-change-or-query-change/48139367#48139367 – Shubham Khatri Feb 20 '19 at 07:06
  • I thought so too at first, but when i put a console.log() statement, the statement is never printed. Therefore, when i setState({someItem: this.props.someItem}); and i call console.log(this.state.someItem); in the render() method, it returns me a blank array. – AKJ Feb 20 '19 at 07:07
  • One more thing to note is that componentWillReceiveProps is not fired on initial render and hence when you navigate away from this component and navigate back to it you are essentially remounting the component and hence at first `componentDidMount`, `constructor` are called. Also if you use v16.3.0 or able `getDerivedStateFromProps` is called – Shubham Khatri Feb 20 '19 at 07:09
  • Please see my edit for the output on my browser. Thank you so much :) – AKJ Feb 20 '19 at 07:10