zoukankan      html  css  js  c++  java
  • react之自定义react-redux的provider、connect

    Provider

    // Provider把store放到context里,所有的子元素可以直接取到store
    import React from 'react'
    import PropTypes from 'prop-types'
    import {bindActionCreators} from './utils.js'
    
    export const connect = (mapStateToProps=state=>state,mapDispatchToProps={})=>(WrapComponent)=>{
    	return class ConnectComponent extends React.Component{
    		static contextTypes = {
    			store:PropTypes.object
    		}
    		constructor(props, context){
    			super(props, context)
    			this.state = {
    				props:{}
    			}
    		}
    		componentDidMount(){
    			const {store} = this.context
    			store.subscribe(()=>this.update())
    			this.update()
    		}
    		update(){
    			const {store} = this.context
    			const stateProps = mapStateToProps(store.getState())
    			const dispatchProps = bindActionCreators(mapDispatchToProps, store.dispatch)
    			this.setState({
    				props:{
    					...this.state.props,
    					...stateProps,
    					...dispatchProps	
    				}
    			})
    		}
    		render(){
    			return <WrapComponent {...this.state.props}></WrapComponent>
    		}
    	}
    }
    
    export class Provider extends React.Component{
    	static childContextTypes = {
    		store: PropTypes.object
    	}
    	getChildContext(){
    		return {store:this.store}
    	}
    	constructor(props, context){
    		super(props, context)
    		this.store = props.store
    	}
    	render(){
    		return this.props.children
    	}
    }
    
    
    

    utils.js

    export function createStore(reducer, enhancer){
    	if (enhancer) {
    		return enhancer(createStore)(reducer)
    	}
    	let currentState = {}
    	let currentListeners = []
    
    	function getState(){
    		return currentState
    	}
    	function subscribe(listener){
    		currentListeners.push(listener)
    	}
    	function dispatch(action){
    		currentState = reducer(currentState, action)
    		currentListeners.forEach(v=>v())
    		return action
    	}
    	dispatch({type:'@IMOOC/WONIU-REDUX'})
    	return { getState, subscribe, dispatch}
    }
    
    // 自定义applyMiddleware函数
    export function applyMiddleware(...middlewares){
    	return createStore=>(...args)=>{
    		const store = createStore(...args)
    		let dispatch = store.dispatch
    
    		const midApi = {
    			getState:store.getState,
    			dispatch:(...args)=>dispatch(...args)
    		}
    		const middlewareChain = middlewares.map(middleware=>middleware(midApi))
    		dispatch = compose(...middlewareChain)(store.dispatch)
    		return {
    			...store,
    			dispatch
    		}
    
    	}
    }
    // 自定义compose函数
    export function compose(...funcs){
    	if (funcs.length==0) {
    		return arg=>arg
    	}
    	if (funcs.length==1) {
    		return funcs[0]
    	}
    	return funcs.reduce((ret,item)=> (...args)=>ret(item(...args)))
    }
    function bindActionCreator(creator, dispatch){
    	return (...args) => dispatch(creator(...args))
    }
    export function bindActionCreators(creators,dispatch){
    	return Object.keys(creators).reduce((ret,item)=>{
    		ret[item] = bindActionCreator(creators[item],dispatch)
    		return ret
    	},{})
    }
    
    
    
  • 相关阅读:
    Activity跳转动画
    如何查询自己的手机版本?欧版、亚太、港行、还是国行?
    VC程序员常用工具汇总
    陈灯可重用代码段管理器VS插件版5.0发布(代码段收集器、个人代码库、代码片段管理、代码管理)
    基于OSLC的系统集成
    安桌点菜源代码
    eclipse jsp 文字设置
    ubuntu 下 netbeans平台 使用C连接mysql
    使用gdi+实时绘制picturebox(画个叉)
    思路上的转变,运用投影和一阶导数的思想
  • 原文地址:https://www.cnblogs.com/raind/p/9690744.html
Copyright © 2011-2022 走看看