A React Component has props and state.
The difference is, that the Component will never change it props. But it can change it's state. This is why a Component will provide you the setState(...) Method, but no setProps(...) Method.
With that said, your approach to change the selected field in this.props is fundamentally not correct. (There also seems to be another problem in your code where you change the selected field in this.props.leads, but provide this.props.people to the table instead of this.props.leads)
Let me give you a basic example as to how I would solve your problem in Pure React (without a state library like Redux):
const Row = ({ item, onClick }) => (
<tr style={styles.row(item.selected)} onClick={() => onClick(item.id)}>...</tr>
)
const Table = ({ items, onRowClick }) => (
<table>
{items.map(item => <Row item={item} onClick={onRowClick} />)}
</table>
)
class PeopleTable extends React.PureComponent {
constructor(props) {
super(props)
this.state = { people: props.people }
}
componentWillReceiveProps(nextProps) {
if (nextProps.people !== this.state.people) {
this.setState({ people: nextProps.people })
}
}
setItemSelectedState(id) {
this.setState((prevState) => {
const people = prevState.people.map(item => ({
...item,
selected: item.id === id ? !item.selected : item.selected,
})
return { people }
})
}
handleRowClick = (id) => this.setItemSelectedState(id)
render() {
return (<Table items={people} onRowClick={this.handleRowClick} />)
}
}
The things to notice here are:
Row and Table are stateless components. They only take props and return jsx. Sometimes they are also referred to as presentational components.
PeopleTable keeps track of the selected state of each item. This is why it needs state and must be a class.
- Because we can't change a components
props, we have to keep a reference to props.people in this.state.
componentWillReceiveProps makes sure that if our components receives another list of people, the state is updated accordingly.
setItemSelectedState goes to the root of your problem. Instead of search and update of the item (like in your this.selectRow(id) method), we create a complete new list of people with map and call setState. setState will trigger a rerender of the component and because we created a new people list, we can use the !== check in componentWillReceiveProps to check if people has changed.
I hope this answer was helpful to your question.
selectedproperty ? If it doesn't know it will not rerender your components. You have two options here: 1) Store yourpeoplearray inside thethis.stateofPeoplecomponent and changeselectedproperty usingthis.setState()method. 2) If you are using redux, store yourpeoplearray inside redux store and changeselectedproperty via redux action.