在单独使用redux的时候 需要手动订阅store里面 感觉特别麻烦 不错的是react有一个组件可以帮我们解决这个问题, 那就是react-redux
。
react-redux
提供了Provider
和 connent
给我们使用。
先说一下几个重点知道的知识
- Provider 就是用来提供store里面的状态 自动getState()
- connent 用来连接store里面的状态
- 为什么要使用connect连接Store 手动subscribe会导致性能上的消耗 手动订阅也不太优雅
- 想要使用store里面的数据需要Provider组件包裹
- 并不是所有的组件都需要搭配redux使用。要区分不同组件的作用。例如: ui组件 不需要 作用是描述ui的骨架、容器组件 描述如何运行(数据获取、状态更新)可以使用
话不多说,直接实战
首先安装 yarn add react-redux
我们前面说了 子组件想要使用store
里面的数据 得先使用Provider
进行包裹
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { Provider } from 'react-redux'; import store from './store'; // 将Provider作为根组件 并提供store给子组件使用 ReactDOM.render( <Provider store={store}> <App /> </Provider> , document.getElementById('root'));
虽然已经提供了store
里面的状态 但是子组件还是没有状态,正常的话需要手动订阅store
里面的改变 当使用了react-redux
之后 直接使用connent
连接store
做映射就 可以直接注入到props
里面
todolist.js
class TodoList extends React.Component { componentDidMount() { // 获得映射的dispatch fetch('http://jsonplaceholder.typicode.com/posts').then((res) => { return res.json() }).then(res => { this.props.getList(res); }) } deleter = (index) => { this.props.delete(index); }; add = () => { this.props.create(); }; change = (e) => { this.props.change() }; render() { const { list } = this.props.add; const { name } = this.props.deleter; return ( <div> <h1>{name}</h1> <button onClick={this.add}>增加</button> <button onClick={this.change}>change</button> { list.map((item, index) => { return <div key={item.id} style={{display: 'flex', justifyContent: "center"}}> <div>{item.title}</div> <div>{item.userId}</div> <button onClick={this.deleter.bind(this, index)}>删除</button> </div> }) } </div> ); } } // 对store里面的状态做一个映射。注入到连接组件的props const mapStateToProps = (state) => { // 是走过reducers的state return state; }; // 传入了这个参数 则连接的组件props里面将不存在dispatch方法 直接将action写在此方法里面 传入到props 会自动dispatch const mapDispatchToProps = (dispatch) => { return { create: () => { dispatch({ type: 'addTodoList', payload: { id: 4, name: '赵六', age: 1 } }); }, delete: (index) => dispatch({ type: 'deleteTodoList', payload: index }), change: () => dispatch({ type: 'change', payload: '王五' }) }; }; // mapDispatchToProps还可以换一种形式写 const mapDispatchToProps1 = { create: () => ({ type: 'addTodoList', payload: { id: 4, name: '赵六', age: 1 } }), delete: (index) => { return { type: 'deleteTodoList', payload: index }; }, change: () => ({ type: 'change', payload: '王五' }), getList: (data) => { return { type: 'getList', payload: data }; } }; // connect() 方法的返回是一个函数 需要传递一个被包裹的组件 可以得知 connect是HOC高阶组件 // 如果你的actions是通过导出形式 还可以换着写 increment只要是函数 返回的是action就会被自动dispatch // 第二个参数可以是action creator // export default connect(mapStateToProps, {increment, decrement})(TodoList) export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
注意
- 千万connent参数顺序不要写反
- mapStateToProps 如果不传递的话 props里面是没有数据的
- 传递了mapDispatchToprops props里面是没有dispatch函数的 如果不传这个函数的话比较自由 dispatch可以随意使用
效果
本文为作者原创,手码不易,允许转载,转载后请以链接形式说明文章出处。