实现一个迷你版的 redux
迷你版 redux 实现
export const createStore = (reducer,enhancer)=>{ if(enhancer) { return enhancer(createStore)(reducer) } let currentState = {} let currentListeners = [] const getState = ()=>currentState const subscribe = (listener)=>{ currentListeners.push(listener) } const dispatch = action=>{ currentState = reducer(currentState, action) currentListeners.forEach(v=>v()) return action } dispatch({type:'@@INIT'}) return {getState,subscribe,dispatch} } //中间件实现 export applyMiddleWare(...middlewares){ return createStore=>...args=>{ const store = createStore(...args) let dispatch = store.dispatch const midApi = { getState:store.getState, dispatch:...args=>dispatch(...args) } const middlewaresChain = middlewares.map(middleware=>middleware(midApi)) dispatch = compose(...middlewaresChain)(store.dispatch) return { ...store, dispatch } } // fn1(fn2(fn3())) 把函数嵌套依次调用 export function compose(...funcs){ if(funcs.length===0){ return arg=>arg } if(funs.length===1){ return funs[0] } return funcs.reduce((ret,item)=>(...args)=>ret(item(...args))) } //bindActionCreator 实现 function bindActionCreator(creator,dispatch){ return ...args=>dispatch(creator(...args)) } function bindActionCreators(creators,didpatch){ //let bound = {} //Object.keys(creators).forEach(v=>{ // let creator = creator[v] // bound[v] = bindActionCreator(creator,dispatch) //}) //return bound return Object.keys(creators).reduce((ret,item)=>{ ret[item] = bindActionCreator(creators[item],dispatch) return ret },{}) }
react-redux 实现
例子 provider 组件就是使用 context,把 store 放到 context 里,所有的子元素可以直接取到 store
import PropTypes from 'prop-types' class Provider extends Component { static childContextTypes = { store:Protypes.object } constructor(props,context){ super(props,context) this.store = props.store } getChildContext(){ //把传进来的 store 放进全局 return {store:this.store} } render(){ return this.props.children } }
connect
负责连接组件,给到 redux
里的数据放到组件的属性里
- 负责接收一个组件,把
state 里
的一些数据放进去,返回一个组件 - 数据变化的时候,能够通知组件
//高阶组件写法 const connect = (mapStateToProps=state=>state,mapDispatchToProps={})=>(wrapperComponent)=>{ return class ConnectComponent extends React.Component { //负责接收组件 static contextTypes = { store:PropTypes.obejct } constructor(props){ super(props, context){ this.state = { props:{} } } } componentDidMount(){ const {store} = this.context store.subscribe(()=>this.update()) this.update() } update(){ // 获取 mapStateToProps、mapDispatchToProps 放入 this.props 里 const {store}=this.context const stateProps = mapStateToProps(store.getState()) const dispatchProps = bindActionCreators(mapDispatchProps,store.dispatch) this.setState({ props:{ ...this.state.props, ...stateProps, ...dispatchProps } }) } render(){ // 把数据放入 return <wrapperComponent {...this.state.props}/> } } }
自己造一个中间件
const thunk = ({dispatch,getState})=>next=>action=>{ if(typeof action == 'function'){ return action(dispatch,getState) } if(Array.isArray(action){ return action.forEach(v=>dispatch(v)) } //默认 什么都不做 return next(action) }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 浅析 React 高阶组件 HOC
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论