反应& Redux:connect()到多个组件&最佳做法

时间:2016-01-27 08:31:38

标签: javascript reactjs redux

我正在研究我的第一个React / Redux项目,我有一个小问题。我已经阅读了文档,并在https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist观看了教程。

但我还有一个问题。这是一个登录页面。 所以我有一个名为LoginForm的表示组件:

组件/ LoginForm.js

import { Component, PropTypes } from 'react'

class LoginForm extends Component {
   render () {
      return (
         <div>
            <form action="#" onSubmitLogin={(e) => this.handleSubmit(e)}>
               <input type="text" ref={node => { this.login = node }} />
               <input type="password" ref={node => { this.password = node }} />
               <input type="submit" value="Login" />
            </form>
         </div>
      )
   }

   handleSubmit(e) {
      e.preventDefault();
      this.props.onSubmitLogin(this.login.value, this.password.value);
   }
}

LoginForm.propTypes = {
   onSubmitLogin: PropTypes.func.isRequired
};

export default LoginForm;

一个名为Login的容器组件,它将数据传递给我的组件。使用react-redux-router,我称之为容器(而不是presentationnal组件):

容器/ Login.js

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))
   }
};

export default connect(null, mapDispatchToProps)(LoginForm);

如您所见,我正在使用redux提供的connect方法来创建我的容器。

我的问题如下:

如果我希望我的Login容器使用多个视图(例如:LoginForm和errorList来显示错误),我需要手动完成(没有连接,因为connect只接受一个参数)。类似的东西:

class Login extends Component {

   render() {
      return (
         <div>
            <errorList />
            <LoginForm onSubmitLogin={ (id, pass) => dispatch(login(id, pass)) } />
         </div>
      )
   }

}

这是一种不好的做法吗?是否更好地创建另一个同时使用errorList和LoginForm的表示组件(LoginPage)并创建一个connect到LoginPage的容器(Login)?

编辑:如果我创建第三个演示组件(LoginPage),我将不得不两次传递数据。像这样:Container -> LoginPage -> LoginForm & ErrorList。 即使有上下文,它似乎也没有办法。

2 个答案:

答案 0 :(得分:27)

我认为你在第二个例子中的内容非常接近。您只能创建一个连接的容器组件并呈现多个表示组件。

在您的第一个示例中,实际上不是一个单独的容器组件:

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 scenario
export default connect(null, mapDispatchToProps)(LoginForm);

即使它位于单独的模块中,您在此处所做的就是直接连接LoginForm

相反,你能做的就是这样:

<强>容器/ 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);

请注意,Login组件现在正传递给connect,使其成为&#34;容器&#34;组件,然后errorListLoginForm都可以呈现。他们的所有数据都可以通过Login容器的道具传递。

答案 1 :(得分:-1)

我确信您需要将所有组件构建为演示组件。您需要一个容器组件,您可以在现有的一个演示文稿上使用{connect}并转换为一个容器组件。

但是,到目前为止,这只是我对React经验不足的看法。