Redux DforDream

Redux

  1. 三个API:createStore() combineReducers() applyMiddleware()

  2. 三个原则:store是只读的、单向数据流、store只能通过纯函数reducer()修改

  3. 三个概念:store、reducer、action

  4. redux定义

    • // npm i redux -S
      import { createStore } from 'redux';
      const initState = {
        msg: 'hello redux',
        list: []
      }
      function reducer (state = initState, action) {
        let newState = JSON.parse(JSON.stringify(state));
        switch (action.type) {
          case 'add':
            newState.msg += action.payload;
            break;
          default:
            break;
        }
        return newState;
      }
      const store = createStore(reducer);
      export default store;
      
  5. redux引入

    • import { Provider } from 'react-redux';
      // Provider包裹app组件
      <Provider store={store}>
         <div className="app">
            <Layout />
         </div>
      </Provider>
      
  6. redux组件内使用

    • import React from 'react';
      // import { connect } from 'react-redux';
      import { useSelector, useDispatch } from 'react-redux';
           
      // 1.使用高阶函数connect使用redux
      // const TestRedux = props => {
      //   console.log('testredux props',props);
      //   return (
      //     <div>
      //       <h1>测试Redux</h1>
      //       <h2>{ props.msg }</h2>
      //       <button onClick={props.changeMsg}>修改msg</button>
      //     </div>
      //   )
      // }
      // function mapStateToProps (store) {
      //   return {
      //     msg: store.msg
      //   }
      // }
      // function mapDispatchToProps (dispatch) {
      //   return {
      //     changeMsg: () => dispatch({ type: 'add', payload: 'hello 2021' })
      //   }
      // }
      // export default connect(mapStateToProps,mapDispatchToProps)(TestRedux);
           
           
      // 2.使用Hooks api的方式使用store
      export default props => {
        const msg = useSelector(store => store.msg);
        const dispatch = useDispatch();
           
        const handleClick = () => {
          dispatch({ type: 'add', payload: 'hello Hooks redux' });
        }
           
        return (
          <div>
             <h1>测试Redux</h1>
             <h2>{ msg }</h2>
            <button onClick={handleClick}>修改msg</button>
          </div>
        )
      }
      
  7. redux只支持dispatch(action)派发同步的action完成一次异步的action,需要被分解成两次同步的action

    • function getMusic (params) {
        return function (dispatch) {
          fetchMusic(params).then(res => {
            dispatch({
              type: 'music',
              payload: res.song.list
            })
          })
        }
      }
           
      dispatch(getMusic(params));
      // 此时报错需要使用异步的action必须使用applyMiddleware
      // dispatch(action)(要求action只能为普通的对象),当react组件中使用dispatch(fn)触发调接口,此时的fn不是plain object ,redux的store收到一个不是plain object的action时,就会报错
      // 解决方法 
      // 当我们在组件中dispatch(xxx)时,thunk对xxx进行判断,如果xxx是plain object,不做任何处理,那么redux的store将收到这个action。如果xxx是function,那么在thunk中,将拦截掉这个xxx,并调用这个xxx()方法。
      npm i redux-thunk -S
      import thunk from 'redux-thunk';
      const store = createStore(reducer,applyMiddleware(thunk));