前言
上两月忙其他的事情,由此学习的步伐暂停了近两个月的时间,现在终于有时间继续啦!之前在学习 redux 的过程中没有整理笔记,继续开始的时候发现知识点居然忘记了好多,还是老话说的好:“好记性不如烂笔头!”;写成一篇文章一是对自己学习过程的记录,也是对知识点的总结,最终目的是为了让知识点掌握的更加牢固~
安装依赖
提供了两个 api
Provider
为后代组件提供 storeconnect
为组件提供数据和变更方法
API
Provider
<Provider store>
使组件层级中的 connect()
方法能够获得 Redux store
。正常情况下,根组件应该嵌套在 <Provider>
中才能使用 connect()
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import './index.css' import App from './App'
import store from './store/'
ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
|
connect
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
连接 React 组件与 Redux store, 返回一个新的已与 Redux store 连接的组件类。
mapStateToProps
mapDispatchToProps
mergeProps
如果指定了这个参数, mapStateToProps()
与 mapDispatchToProps()
的执行结果和组件自身的 props
将传入到这个回调函数中。该回调函数返回的对象将作为 props
传递到被包装的组件中。你也许可以用这个回调函数,根据组件的 props
来筛选部分的 state
数据,或者把 props
中 的某个特定变量与 action creator
绑定在一起。如果你省略这个参数,默认情况下返回Object.assign({}, ownProps, stateProps, dispatchProps)
的结果。
react-redux 使用 类组件
store/index
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import { createStore, applyMiddleware, combineReducers } from 'redux' import thunk from 'redux-thunk' import logger from 'redux-logger' import promise from 'redux-promise'
function countReducer(state = 0, action) { switch (action.type) { case 'ADD': return state + (action.payload || 1) case 'MINUS': return state - (action.payload || 1) default: return state } }
const store = createStore( combineReducers({ count: countReducer }), applyMiddleware(thunk, promise, logger) )
export default store
|
pages/reactReduxPage
通过 connect 的mapStateToProps
映射state
、mapDispatchToProps
映射dispatch
到组件的props
身上;
mapDispatchToProps
可以是对象形式,也可以是函数形式:
对象:组件 props 身上就会有具体的 dispatch 方法;
函数:组件身上会有具体的方法,还有 redux 的 dispatch 方法,redux 提供了 bindActionCreators
帮助我们写mapDispatchToProps
注意:mapStateToProps
、mapDispatchToProps
的第二个参数都是ownProps
,慎用!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| @connect( ({ count }) => ({ count }),
(dispatch) => { let creators = { add: () => ({ type: 'ADD' }), minus: () => ({ type: 'MINUS' }), }
creators = bindActionCreators(creators, dispatch) return { dispatch, ...creators } } ) class ReactReduxPage extends React.Component { render() { const { count, dispatch, add, minus } = this.props
return ( <div> <h1>ReactReduxPage</h1> <p>{count}</p> <button onClick={add}>ADD</button> <button onClick={minus}>MINUS</button> <button onClick={() => { dispatch({ type: 'ADD' }) }} > dispatch </button> </div> ) } }
|
写装饰器的话,@connet 里面看起来会比较乱,一般在写项目的时候都会把mapStateToProps
和mapDispatchToProps
写到组件的下边:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux'
class ReactReduxPage extends React.Component { render() { const { count, dispatch, add, minus } = this.props
return ( <div> <h1>ReactReduxPage</h1> <p>{count}</p> <button onClick={add}>ADD</button> <button onClick={minus}>MINUS</button> <button onClick={() => { dispatch({ type: 'ADD' }) }} > dispatch </button> </div> ) } }
const mapStateToProps = ({ count }) => ({ count })
const mapDispatchToProps = (dispatch) => { let creators = { add: () => ({ type: 'ADD' }), minus: () => ({ type: 'MINUS' }), } creators = bindActionCreators(creators, dispatch) return { dispatch, ...creators } }
export default connect(mapStateToProps, mapDispatchToProps)(ReactReduxPage)
|
react-redux 使用 函数组件
store 的注入根组件等方法和上面的类组件都是一样的,区别就在组件内部使用 store 数据的区别,hook 的方法会更加的简洁和方便;
主要是利用react-redux
提供的 useSelecter
、useDispatch
两个 hook;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import React from 'react' import { useSelector, useDispatch } from 'react-redux'
const ReactReduxHookPage = () => { const count = useSelector(({ count }) => count) const dispatch = useDispatch()
const add = () => { dispatch({ type: 'ADD' }) }
const minus = () => { dispatch({ type: 'MINUS' }) }
return ( <div> <h1>ReactReduxHookPage</h1> <p>{count}</p> <button onClick={add}>ADD</button> <button onClick={minus}>MINUS</button> <button onClick={() => {dispatch({ type: 'ADD' })}}>dispatch</button> </div> ) }
export default ReactReduxHookPage
|
总结
以上记录了react-redux的基本使用,尚未涉及处理异步情况,处理异步问题计划另起一篇文章去详细讲述。
很多人在学习react的时候感觉很难,我猜大部分就是对这个react-redux拎不清,其实使用方法都很简单,主要就是react、react-redux写法都很自由,一但项目大起来,如何优雅的去编写项目代码保证项目具有良好的扩展性、阅读性、以及代码的健壮性,确实是一个需要重要关注的点。