score:1

React 16.3 includes a static function getDerivedStateFromProps(nextProps, prevState), which will be invoked after initial mount as well as when it receives new props. See https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

score:3

The componentWillReceiveProps() method is not called for the initial render. What could do, if you only intend to use the data from props as the initial data, is something like:

getInitialState () {
  return {
    contacts: this.props.data.contacts
  }
}

In the React docs they suggest you name the props initialContacts, just to make it really clear that the props' only purpose is to initialize something internally.

Now if you want it to update when this.props.contacts change, you could use componentWillReceiveProps() like you did. But I'm not sure it's the best idea. From the docs:

Using props to generate state in getInitialState often leads to duplication of "source of truth", i.e. where the real data is. This is because getInitialState is only invoked when the component is first created.

Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.

score:10

Your approach to use both redux store and local store is correct.

Just do not try to duplicate the state from redux store in your component. Keep referring to it via props.

Instead create a sortedContacts function that computes value on the fly by applying locally-stored sortBy param to redux-stored contacts.

const Table extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      sortBy: 'id' // default sort param
    }
  }

  sortContacts(param) {
    this.setState({ sortBy: param})
  }

  sortedContacts() {
    return this.props.contacts.sort(...); // return sorted collection
  }

  render() {
    return (
      <table>
        <thead>
          <tr>
            <th onClick={() => this.sortContacts("firstName")}>First Name</th>
          </tr>
        </thead>
        <tbody>
          {this.sortedContacts()}
        </tbody>
      </table>
    )
  }
}

Related Query

More Query from same tag