我正在阅读 Redux 库的文档,它有这个例子:
除了读取状态,容器组件还可以调度动作。以类似的方式,您可以定义一个名为 mapDispatchToProps() 的函数,该函数接收 dispatch() 方法并返回要注入到演示组件中的回调 props。
这实际上没有任何意义。既然已经有 mapStateToProps
,为什么还需要 mapDispatchToProps
?
他们还提供了这个方便的代码示例:
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
这是什么功能,为什么有用?
我觉得没有一个答案明确说明为什么 mapDispatchToProps
有用。
这实际上只能在 container-component
模式的上下文中回答,我发现首先阅读:Container Components 然后 Usage with React 才能最好地理解。
简而言之,您的 components
应该只关心显示内容。 他们应该从中获取信息的唯一地方是他们的道具。
与“显示的东西”(组件)分开的是:
你如何让这些东西显示出来,
以及你如何处理事件。
这就是 containers
的用途。
因此,模式中“精心设计”的 component
如下所示:
class FancyAlerter extends Component {
sendAlert = () => {
this.props.sendTheAlert()
}
render() {
<div>
<h1>Today's Fancy Alert is {this.props.fancyInfo}</h1>
<Button onClick={sendAlert}/>
</div>
}
}
看看这个组件如何从 props(通过 mapStateToProps
来自 redux 商店)获取它显示的信息,它还从它的 props 获取它的操作函数:sendTheAlert()
。
这就是 mapDispatchToProps
的用武之地:在相应的 container
// FancyButtonContainer.js
function mapDispatchToProps(dispatch) {
return({
sendTheAlert: () => {dispatch(ALERT_ACTION)}
})
}
function mapStateToProps(state) {
return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}
export const FancyButtonContainer = connect(
mapStateToProps, mapDispatchToProps)(
FancyAlerter
)
我想知道您是否可以看到,现在是 container
1 了解 redux 和 dispatch 以及 store 和 state 等等。
模式中的 component
,FancyAlerter
,它不需要知道任何这些东西:它通过它的 props 获取在按钮的 onClick
处调用的方法。
而且... mapDispatchToProps
是 redux 提供的有用方法,可以让容器轻松地将函数传递到其 props 上的包装组件中。
所有这些看起来很像文档中的待办事项示例,以及此处的另一个答案,但我试图根据模式对其进行投射以强调原因。
(注意:您不能将 mapStateToProps
用于与 mapDispatchToProps
相同的目的,因为您无权访问 mapStateToProp
中的 dispatch
。所以您不能使用 mapStateToProps
来提供被包装的组件是一个使用 dispatch
的方法。
我不知道他们为什么选择将它分成两个映射函数 - 让 mapToProps(state, dispatch, props)
IE 一个函数同时完成这两个函数可能会更整洁!
1 请注意,我特意将容器明确命名为 FancyButtonContainer
,以强调它是一个“事物”——作为“事物”的容器的身份(因此存在!)有时会在简写中丢失
export default connect(...)
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
大多数示例中显示的语法
它基本上是一个简写。所以不必写:
this.props.dispatch(toggleTodo(id));
您将使用示例代码中所示的 mapDispatchToProps,然后在其他地方编写:
this.props.onTodoClick(id);
或更可能在这种情况下,您将其作为事件处理程序:
<MyComponent onClick={this.props.onTodoClick} />
Dan Abramov 在此处提供了一个有用的视频:Redux: Generating Containers with connect() from React Redux (VisibleTodoList)
mapDispatch
函数,Redux 将使用默认值。该默认 mapDispatch
函数仅采用 dispatch
函数引用,并将其作为 this.props.dispatch
提供给您。
mapStateToProps()
是一个实用程序,可帮助您的组件获取更新状态(由其他一些组件更新),
mapDispatchToProps()
是一个实用程序,可帮助您的组件触发动作事件(调度动作可能会导致应用状态)
react-redux
库中的 mapStateToProps
、mapDispatchToProps
和 connect
提供了一种方便的方式来访问您商店的 state
和 dispatch
功能。所以基本上 connect 是一个高阶组件,如果这对您有意义,您也可以将其视为包装器。因此,每次您的 state
更改时,都会使用您的新 state
调用 mapStateToProps
,随后当您 props
更新组件时,将运行渲染函数以在浏览器中渲染您的组件。 mapDispatchToProps
还在组件的 props
上存储键值,它们通常采用函数的形式。通过这种方式,您可以从您的组件 onClick
、onChange
事件中触发 state
更改。
来自文档:
const TodoListComponent = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
function toggleTodo(index) {
return { type: TOGGLE_TODO, index }
}
const TodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
还要确保您熟悉 React stateless functions 和 Higher-Order Components
现在假设 redux 有一个动作:
export function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
当你导入它时,
import {addTodo} from './actions';
class Greeting extends React.Component {
handleOnClick = () => {
this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
}
render() {
return <button onClick={this.handleOnClick}>Hello Redux</button>;
}
}
const mapDispatchToProps = dispatch => {
return {
onTodoClick: () => { // handles onTodoClick prop's call here
dispatch(addTodo())
}
}
}
export default connect(
null,
mapDispatchToProps
)(Greeting);
正如函数名所说的 mapDispatchToProps()
,将 dispatch
动作映射到 props(我们组件的 props)
所以 prop onTodoClick
是 mapDispatchToProps
函数的关键,它进一步委托调度动作 addTodo
。
此外,如果您想修剪代码并绕过手动实现,那么您可以这样做,
import {addTodo} from './actions';
class Greeting extends React.Component {
handleOnClick = () => {
this.props.addTodo();
}
render() {
return <button onClick={this.handleOnClick}>Hello Redux</button>;
}
}
export default connect(
null,
{addTodo}
)(Greeting);
这究竟意味着
const mapDispatchToProps = dispatch => {
return {
addTodo: () => {
dispatch(addTodo())
}
}
}
mapStateToProps
接收 state
和 props
并允许您从状态中提取道具以传递给组件。
mapDispatchToProps
接收 dispatch
和 props
,用于将动作创建者绑定到调度,以便在执行结果函数时调度动作。
我发现这只会使您不必在组件中执行 dispatch(actionCreator())
,从而使其更易于阅读。
React redux: connect: Arguments
dispatch
方法的价值是什么?它从何而来?
<Provider/>
本身提供的增强功能。它执行自己的高阶组件魔法,以确保调度在其子组件中可用。
ALERT_ACTION
是动作函数还是从动作函数返回的type
? :/ 很困惑