React & Redux : connect() to multiple components & best practices
I think that what you have in your second example is very close. You can create just one container component that's connected and render multiple presentational components.
In your first example, there actually isn't a separate container component:
import { connect } from 'react-redux'import { login } from '../actions/creators/userActionCreators'import LoginForm from '../components/LoginForm'const mapDispatchToProps = (dispatch) => { return { onSubmitLogin: (id, pass) => dispatch(login(id, pass)) }};// `LoginForm` is being passed, so it would be the "container"// component in this scenarioexport default connect(null, mapDispatchToProps)(LoginForm);
Even though it's in a separate module, what you're doing here is connecting your LoginForm
directly.
Instead, what you can do is something like this:
containers/Login.js
import { connect } from 'react-redux'import { login } from '../actions/creators/userActionCreators'import LoginForm from '../components/LoginForm'import ErrorList from '../components/ErrorList'class Login extends Component { render() { const { onSubmitLogin, errors } = this.props; return ( <div> <ErrorList errors={errors} /> <LoginForm onSubmitLogin={onSubmitLogin} /> </div> ) }}const mapDispatchToProps = (dispatch) => { return { onSubmitLogin: (id, pass) => dispatch(login(id, pass)) }};const mapStateToProps = (state) => { return { errors: state.errors };};export default connect(mapStateToProps, mapDispatchToProps)(Login);
Note that the Login
component is now being passed to connect
, making it the "container" component and then both the errorList
and LoginForm
can be presentational. All of their data can be passed via props by the Login
container.
I truly believe that you need to build all your components as Presentational Components. At the moment you need a Container Component, you might use {connect} over one of the existing Presentational and convert into a Container one.
But, that is only my view with short experience in React so far.