反应& Redux:connect()到多个组件&最佳做法 [英] React & Redux : connect() to multiple components & best practices
问题描述
我正在研究我的第一个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.
这篇关于反应& Redux:connect()到多个组件&最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!