In my React application, I have two distinct types of components: presentations and containers. It\'s roughly after Dan Abromov\'s \"Presentational and Con
If you don't want to use Flux or Redux yet, then updating peer-components (in your case, UsersListContainer and AddUserContainer) is a bit, in my opinion, anti-pattern for React.
The main idea of React is, to me, passing props from parent to children, therefore, Irvin Lim's idea to "got rid of UsersListContainer but moved AddUserContainer into UsersContainer" will make it easier for you to control when to update your component!
Your current approaching and my idea are the same: in your UsersContainer, create a method to forceUpdate it, then pass it along to AddUserContainer, and after this AddUserContainer added a user, you trigger that updating method on the parent:
<AddUserContainer onUserAdded={ this.props.updatingParent } />
For your reference, or for anyone else who wants to understand about how to update the parent component whenever child (or grandchild or great-grandchild) updates, please refer to my answer to another similar issue:
Re-initializing class on redirect
If you still keep your current component-hierarchy, when UsersContainer is updated, its child-components (UsersListContainer and AddUserContainer) will be updated, too. However, AddUserContainer will once again be updated!
As a result, I still think in your case, using Flux or Redux is a nice approaching, which eliminates to complexity of passing props through many levels of deep & complicated component-hierarchy
Check out react-refetch, which provides a nice API for fetch
ing, and allows you to implement the Presentational and Container Components pattern, without using Flux/Redux for API calls.
It also lets you handle loading and errored states, which is definitely necessary for a decent web application today.
In the example below, I got rid of UsersListContainer
but moved AddUserContainer
into UsersContainer
as well. This makes your UsersListView
the presentational component for UsersContainer
. Feel free to change the naming as you wish. This is so that I can get the refreshUsers
prop to pass into AddUserContainer
.
// UsersContainer.js
const Container = ({ usersFetch, refreshUsers }) => {
if (userFetch.pending) {
return <LoadingDisplay />
} else if (usersFetch.rejected) {
return <ErrorDisplay error={ usersFetch.reason } />
} else if (usersFetch.fulfilled) {
return (
<UsersListView users={ usersFetch.value } />
<AddUserContainer handleAddUser={ refreshUsers } />
);
}
};
const refetch = (props) => {
const usersFetch = `/api/users`;
return {
usersFetch: usersFetch,
refreshUsers: () => ({
usersFetch: { ...usersFetch, force: true, refreshing: true }
}),
};
};
export default connect(refetch)(Container);
Check out the documentation for more examples. I personally prefer to use react-refetch for API-heavy applications, rather than implementing the calls in Redux.