redux 入门学习

217 阅读2分钟

数据流程

view通过dispatch触发action,store监听到action,通过reducer更新计算数据,然后再更新view image.png

import './App.css';
import { createStore } from 'redux';

function renducer(state={count:0},action){
  switch (action.type) {
    case "ADD_TODO":
      return {...state,count:state.count+1}

    default:
     return state
  }

}
const store=createStore(renducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
function click(){
  store.dispatch({
    type: 'ADD_TODO',
    payload: 'Learn Redux'
  });
}
store.subscribe(()=>{
  console.log(store.getState(),'22')
});
function App() {
  return (
    <div className="App">
     {store.getState().count}
     <div onClick={click}>点击</div>
    </div>
  );
}

export default App;

createStore简单实现

  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    }
  };

  dispatch({});

  return { getState, dispatch, subscribe };
};

combineReducers用法

function renducer(state={count:0},action){
  switch (action.type) {
    case "ADD_TODO":
      return {...state,count:state.count+1}

    default:
     return state
  }

}
function renducer1(state={count1:0},action){
  switch (action.type) {
    case "ADD_TODO1":
      return {...state,count:state.count1+1}

    default:
     return state
  }

}
const dd=combineReducers({
  renducer,
  renducer1
})
const store=createStore(dd, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

下面是combineReducer的简单实现。

  return (state = {}, action) => {
    return Object.keys(reducers).reduce(
      (nextState, key) => {
        nextState[key] = reducers[key](state[key], action);
        return nextState;
      },
      {} 
    );
  };
};

中间件

但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。

怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。

image.png

image.png

image.png 上面代码中,applyMiddleware方法的三个参数,就是三个中间件。有的中间件有次序要求,使用前要查一下文档。比如,logger就一定要放在最后,否则输出结果会不正确。

看到这里,你可能会问,applyMiddlewares这个方法到底是干什么的?

它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。下面是它的源码。

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer);
    var dispatch = store.dispatch;
    var chain = [];

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    };
    chain = middlewares.map(middleware => middleware(middlewareAPI));
    dispatch = compose(...chain)(store.dispatch);

    return {...store, dispatch}
  }
}

上面代码中,所有中间件被放进了一个数组chain,然后嵌套执行,最后执行store.dispatch。可以看到,中间件内部(middlewareAPI)可以拿到getState和dispatch这两个方法。

react-thunk

action可以接收异步函数 image.png image.png

image.png

redux-promise

image.png

image.png

阮老师文档

juejin.cn/post/684490… redux基本实现

www.ruanyifeng.com/blog/2016/0…