前言
上两月忙其他的事情,由此学习的步伐暂停了近两个月的时间,现在终于有时间继续啦!之前在学习 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 连接的组件类。
mapStateToPropsmapDispatchToPropsmergeProps
如果指定了这个参数, 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写法都很自由,一但项目大起来,如何优雅的去编写项目代码保证项目具有良好的扩展性、阅读性、以及代码的健壮性,确实是一个需要重要关注的点。