ReactCollect
ReactCollect copied to clipboard
关于react-redux中, connect方法的mapStateToProps和mapDispatchToProps
问题:
- mapStateToProps和mapDispatchToProps的写法
- mapStateToProps和mapDispatchToProps这两个参数是必须的吗
- mapStateToProps和mapDispatchToProps各自代表什么意思
1)写法
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from './TodoList'
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_ALL':
return todos;
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed);
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed);
default:
throw new Error('Unknown filter: ' + filter)
}
};
const mapStateToProps = (state) => ({
todos: getVisibleTodos(state.todos, state.visibilityFilter)
});
const mapDispatchToProps = ({
onTodoClick: toggleTodo
});
const TodoListContainer = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList);
export default TodoListContainer
2) 不是必须的(可以都不传,也可以只传一个)
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
/**
* 这里用了let没用const,因为下面有 AddTodo = connect()(AddTodo)
*/
const AddTodo = ({dispatch}) => {
let input;
return (
<div>
<form onSubmit={e => {
e.preventDefault();
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value));
input.value = ''
}}>
<input ref={node => {
input = node
}} />
<button type="submit">
Add Todo
</button>
</form>
</div>
)
};
const AddTodoContainer= connect()(AddTodo);
export default AddTodoContainer;
经过测试发现如果不在mapStateToProps和mapDispatchToProps中指定要传入UI组件AddTodo的数据和回调函数,则AddTodo组件只能访问到dispatch这个store中的api, 用于触发action,我记得redux中有提到可以在任何地方dispatch
参考资料:React 实践心得:react-redux 之 connect 方法详解
connect 详解
究竟 connect 方法到底做了什么,我们来一探究竟。
首先看下函数的签名:
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
connect() 接收四个参数,它们分别是 mapStateToProps , mapDispatchToProps , mergeProps 和 options
mapStateToProps(state, ownProps) : stateProps
这个函数允许我们将 store 中的数据作为 props 绑定到组件上
函数的第二个参数 ownProps ,是 MyComp 自己的 props
mapDispatchToProps(dispatch, ownProps): dispatchProps
connect 的第二个参数是 mapDispatchToProps ,它的功能是,将 action 作为 props 绑定到 MyComp 上
Redux 本身提供了 bindActionCreators 函数,来将 action 包装成直接可被调用的函数
疑问:bindActionCreators是什么?
参考资料:阮一峰;Redux 入门教程(三):React-Redux 的用法
关于mapStateToProps
- mapStateToProps是一个函数
- 作为函数,mapStateToProps执行后应该返回一个对象,里面的每一个键值对就是一个映射
- mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染
- mapStateToProps的第一个参数总是state对象,还可以使用第二个参数,代表容器组件的props对象
- 使用ownProps作为第二个参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染
- connect方法可以省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新
关于mapDispatchToProps
- mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射
- 也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象
- 如果mapDispatchToProps是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数
- 如果mapDispatchToProps是一个对象,它的每个键名也是对应 UI 组件的同名参数,键值应该是一个函数,会被当作 Action creator ,返回的 Action 会由 Redux 自动发出
bindActionCreators() 可以自动把多个 action 创建函数 绑定到 dispatch() 方法上。 https://cn.redux.js.org/docs/basics/Actions.html
@ricocai 这个已经是很久以前的issue了,我现在也不用redux,推荐mobx
connect 是一个科里化函数??
@pengliheng 是一个高阶函数
const mapDispatchToProps = (dispatch, ownProps) => {
return {
setSignIn: (payload) => {
dispatch({type: 'note/sign_In', payload})
}
}
}
export default connect(mapDispatchToProps)(Info)
我只传一个的时候,为啥会报这个错误啊 加上connect中加上这个mapStateToProps则会正常运行了
用的是dvs