如何从三层以下的子组件调度动作?
How to dispatch actions from Child components three level down?
我目前在设计 React 应用程序时遇到这个问题,我似乎无法找到答案。
所以我的应用程序在 React Router 中具有以下组件层次结构
应用程序
-> 动态容器
-> -> 登录组件
现在,LoginComponents 具有用于获取用户名和密码的表单元素。
我有处理登录的 userActionCreators,它会在完成后分派登录成功,但我似乎无法找到连接我的 LoginComponent 以分派操作或调用 actionCreators 的正确方法。
我该怎么做?如有任何建议,我们将不胜感激。
两个选项:
通过 props
对象将绑定的 actionCreator 从容器(连接到 Redux)向下传递到子组件(未连接到 Redux)。
考虑在您的项目中采用 React Component Context。
一种选择是使用 connect
将您的单一用途表单绑定到它们的操作。由于 <LoginComponent />
通常总是做完全相同的事情,您可以像这样使用它:
import React from 'react';
import * as userActionCreators from '../actions/users';
import { connect } from 'react-redux';
export class LoginComponent extends React.Component {
static propTypes = {
login: React.PropTypes.func.isRequired
}
render() {
const { login } = this.props;
const { username, password } = this.state;
return (
<form onSubmit={ () => login(username, password) }>
...
</form>
);
}
}
export default connect(null, userActionCreators)(LoginComponent);
connect
自动绑定action creator,单独提供dispatch
给props
,所以如果想说的更明确一点,上面的例子和[=19=一样]
import React from 'react';
import { login } from '../actions/users';
import { connect } from 'react-redux';
export class LoginComponent extends React.Component {
static propTypes = {
dispatch: React.PropTypes.func.isRequired
}
render() {
const { login, dispatch } = this.props;
const { username, password } = this.state;
return (
<form onSubmit={ () => dispatch(login(username, password)) }>
...
</form>
);
}
}
export default connect()(LoginComponent);
作为参考,userActionCreators
:
const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
const LOGIN_FAILED = 'LOGIN_FAILED';
export function login(username, password) {
if (username === 'realUser' && password === 'secretPassword') {
return { type: LOGIN_SUCCESS, payload: { name: 'Joe', username: 'realUser' } };
} else {
return { type: LOGIN_FAILED, error: 'Invalid username or password };
}
}
如果我理解正确,如果你阅读 Example: Todo List | Redux,你会找到你可能正在寻找的示例。
有 App 组件,connect()ed 到 Redux,然后是其他组件:AddTodo、TodoList、Todo 和 Footer.
App 调用 TodoList,后者调用 Todo,用户可以在其中单击某些内容。这个点击回调后会返回回调,从Todo到TodoList再到App具体如下:
App 调用 TodoList
<TodoList todos={visibleTodos} onTodoClick={ index => dispatch(completeTodo(index)) } />
TodoList 调用 Todo
<Todo {...todo} key={index} onClick={ () => this.props.onTodoClick(index) } />
Todo 组件有一个 <li>
和 onClick={this.props.onClick}
属性.
因此,向后,当有人在 Todo 组件中单击时,将调用 this.props.onClick
,这将从 TodoList 调用 this.props.onTodoClick(index)
(注意可选的添加参数 index),最后,这将从 App[=57= 调用函数 dispatch(completeTodo(index))
].
我目前在设计 React 应用程序时遇到这个问题,我似乎无法找到答案。
所以我的应用程序在 React Router 中具有以下组件层次结构
应用程序 -> 动态容器 -> -> 登录组件
现在,LoginComponents 具有用于获取用户名和密码的表单元素。
我有处理登录的 userActionCreators,它会在完成后分派登录成功,但我似乎无法找到连接我的 LoginComponent 以分派操作或调用 actionCreators 的正确方法。
我该怎么做?如有任何建议,我们将不胜感激。
两个选项:
通过
props
对象将绑定的 actionCreator 从容器(连接到 Redux)向下传递到子组件(未连接到 Redux)。考虑在您的项目中采用 React Component Context。
一种选择是使用 connect
将您的单一用途表单绑定到它们的操作。由于 <LoginComponent />
通常总是做完全相同的事情,您可以像这样使用它:
import React from 'react';
import * as userActionCreators from '../actions/users';
import { connect } from 'react-redux';
export class LoginComponent extends React.Component {
static propTypes = {
login: React.PropTypes.func.isRequired
}
render() {
const { login } = this.props;
const { username, password } = this.state;
return (
<form onSubmit={ () => login(username, password) }>
...
</form>
);
}
}
export default connect(null, userActionCreators)(LoginComponent);
connect
自动绑定action creator,单独提供dispatch
给props
,所以如果想说的更明确一点,上面的例子和[=19=一样]
import React from 'react';
import { login } from '../actions/users';
import { connect } from 'react-redux';
export class LoginComponent extends React.Component {
static propTypes = {
dispatch: React.PropTypes.func.isRequired
}
render() {
const { login, dispatch } = this.props;
const { username, password } = this.state;
return (
<form onSubmit={ () => dispatch(login(username, password)) }>
...
</form>
);
}
}
export default connect()(LoginComponent);
作为参考,userActionCreators
:
const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
const LOGIN_FAILED = 'LOGIN_FAILED';
export function login(username, password) {
if (username === 'realUser' && password === 'secretPassword') {
return { type: LOGIN_SUCCESS, payload: { name: 'Joe', username: 'realUser' } };
} else {
return { type: LOGIN_FAILED, error: 'Invalid username or password };
}
}
如果我理解正确,如果你阅读 Example: Todo List | Redux,你会找到你可能正在寻找的示例。
有 App 组件,connect()ed 到 Redux,然后是其他组件:AddTodo、TodoList、Todo 和 Footer.
App 调用 TodoList,后者调用 Todo,用户可以在其中单击某些内容。这个点击回调后会返回回调,从Todo到TodoList再到App具体如下:
App 调用 TodoList
<TodoList todos={visibleTodos} onTodoClick={ index => dispatch(completeTodo(index)) } />
TodoList 调用 Todo
<Todo {...todo} key={index} onClick={ () => this.props.onTodoClick(index) } />
Todo 组件有一个
<li>
和onClick={this.props.onClick}
属性.
因此,向后,当有人在 Todo 组件中单击时,将调用 this.props.onClick
,这将从 TodoList 调用 this.props.onTodoClick(index)
(注意可选的添加参数 index),最后,这将从 App[=57= 调用函数 dispatch(completeTodo(index))
].