反应& Redux:connect()到多个组件&最佳做法 [英] React & Redux : connect() to multiple components & best practices

查看:89
本文介绍了反应& Redux:connect()到多个组件&最佳做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on my first React/Redux project and I have a little question. I've read the documentation and watched the tutorials available at https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist.

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

But I still have one question. It's about a login page. So I have a presentational component named 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组件):

And a container component named Login which pass data to my component. Using react-redux-router, I call this container (and not the presentationnal component) :

containers / 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);

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

As you can see, I'm using the connect method provide by redux to create my container.

我的问题如下:

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

If I want my Login container to use multiple views (for example : LoginForm and errorList to display errors), I need to do it by hand (without connect because connect take only one argument). Something like :

class Login extends Component {

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

}

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

Is it a bad practice ? Is it better to create another presentational component (LoginPage) which use both errorList and LoginForm and create a container (Login) which connect to LoginPage ?

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

If I create a third presentational component (LoginPage), I'll have to pass data twice. Like this : Container -> LoginPage -> LoginForm & ErrorList. Even with context, it don't seems to be the way to go.

推荐答案

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

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

即使它在一个单独的模块中,你在这里做的是连接 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);

请注意登录组件现在正在传递到 connect ,使其成为容器组件,然后传递给 errorList LoginForm 可以是表现性的。所有数据都可以通过 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.

这篇关于反应&amp; Redux:connect()到多个组件&amp;最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆