I'm trying to separate a presentational component from a container component. I have a SitesTable
and a SitesTableContainer
. The container is responsible for triggering redux actions to fetch the appropriate sites based on the current user. The problem is the current user is fetched asynchronously, after the container component gets rendered initially. This means that the container component doesn't know that it needs to re-execute the code in its componentDidMount
function which would update the data to send to the SitesTable
. I think i need to rerender the container component when one one of its props(user) changes. How do i do this correctly?
class SitesTableContainer extends React.Component {
static get propTypes() {
return {
sites: React.PropTypes.object,
user: React.PropTypes.object,
isManager: React.PropTypes.boolean
}
}
componentDidMount() {
if (this.props.isManager) {
this.props.dispatch(actions.fetchAllSites())
} else {
const currentUserId = this.props.user.get('id')
this.props.dispatch(actions.fetchUsersSites(currentUserId))
}
}
render() {
return <SitesTable sites={this.props.sites}/>
}
}
function mapStateToProps(state) {
const user = userUtils.getCurrentUser(state)
return {
sites: state.get('sites'),
user,
isManager: userUtils.isManager(user)
}
}
export default connect(mapStateToProps)(SitesTableContainer);
I would recommend having a look at this answer of mine, and see if it is relevant to what you are doing. If I understand your real problem, it's that your just not using your async action correctly and updating the redux "store", which will automatically update your component with it's new props.
This section of your code:
Should not be triggering in a component, it should be handled after executing your first request.
Have a look at this example from redux-thunk:
You don't necessarily have to use redux-thunk, but it will help you reason about scenarios like this and write code to match.
You have to add a condition in your
componentWillReceiveProps
method.This is how your component should look like
UPDATE (React 17)
Looks like
componentWillReceiveProps
is going to be removed in React 17. You can usecomponentDidUpdate
instead ofcomponentWillReceiveProps
to achieve the same thing.The new example is using
fast-deep-equal
instead ofJSON.stringify()
to compare the objects.I think that is the event you need.
componentWillReceiveProps
triggers whenever your component receive something through props. From there you can have your checking then do whatever you want to do.ComponentWillReceiveProps()
is going to be deprecated in the future due to bugs and inconsistencies. An alternative solution for re-rendering a component on props change is to useComponentDidUpdate()
andShouldComponentUpdate()
.ComponentDidUpdate()
is called whenever the component updates AND ifShouldComponentUpdate()
returns true (IfShouldComponentUpdate()
is not defined it returnstrue
by default).This same behavior can be accomplished using only the
ComponentDidUpdate()
method by including the conditional statement inside of it.If one attempts to set the state without a conditional or without defining
ShouldComponentUpdate()
the the component will infinitely re-render