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
    	},{})
    }
    
    
    
  • 相关阅读:
    您认为在测试人员同开发人员的沟通过程中,如何提高沟通的效率和改善沟通的效果?维持测试人员同开发团队中其他成员良好的人际关系的关键是什么?
    redis和jedis的用法,区别
    Jedis实现多种功能总结
    Druid简单介绍
    Svn与Git的区别
    SVN的一些基本概念(学前了解)
    Redis-cli 的功能
    postman的使用方法
    Spring Boot 有哪些优点?
    Redis中的常用命令哪些?
  • 原文地址:https://www.cnblogs.com/raind/p/9690744.html
Copyright © 2011-2022 走看看