【问题标题】:React & Redux : connect() to multiple components & best practicesReact & Redux : connect() 到多个组件和最佳实践
【发布时间】:2016-05-04 02:24:08
【问题描述】:

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

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

components/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 方法来创建我的容器。

我的问题如下:

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

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 -&gt; LoginPage -&gt; LoginForm &amp; ErrorList。 即使有上下文,它似乎也不是要走的路。

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    我真的相信您需要将所有组件构建为展示组件。在您需要一个容器组件的那一刻,您可以使用 {connect} 覆盖现有的展示组件之一并转换为容器组件。

    但是,这只是我目前对 React 的短暂经验的看法。

    【讨论】:

      【解决方案2】:

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

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

      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,使其成为“容器”组件,然后errorListLoginForm 都可以呈现。他们所有的数据都可以通过 Login 容器的 props 传递。

      【讨论】:

        猜你喜欢
        • 2022-12-01
        • 2021-08-19
        • 1970-01-01
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-18
        相关资源
        最近更新 更多