react-redux源码解析

310 阅读1分钟

React-redux 介绍

为什么会有react-redux库

  • store需要被所有的子组件使用 都需要传递
  • 当发送dispatch的时候,如果需要更新,还需要用户手动监听subscribe

react-redux 解决了什么样的问题

  • 我们不用管在哪个组件中使用store 里面的方法
  • 通过connect高阶封装的hoc 把store里面的方法 放到组件的props上
  • 最重要的就是实现 Provider 和 connect

Provider

export const Provider = ({ store,children })=>{
    return <Context.Provider value={ store } > { children } </Context.Provider>
}

connect

分析一下 connect的使用

connect(
	mapStateToProps,
    mapDispatchToProps
)

mapStateToProps 这个接受state 返回一个对象 ({count}) => ({ count }), mapDispatchToProps 这里面接受两种参数

  • 函数 参数就是dipatch
函数
dispatch => {
	return {
		dispatch
	}
}
对象
{
   add: () => ({type:'ADD'})
}

connect的解析

export const connect = (
    mapStateToProps,
    mapDispatchToProps
) => WrappedComponent => props => {
    let store = useContext(Context)
    let { getState,dispatch,subscribe } = store;
    let stateToProps = mapStateToProps(getState()) // { count: 1 }
    let dispatchToProps = { dispatch };
    if( typeof mapDispatchToProps === 'object' ){
        dispatchToProps = bindActionCreators(mapDispatchToProps,dispatch)
    }else if(typeof mapDispatchToProps === 'function' ){
        dispatchToProps = mapDispatchToProps(dispatch)
    }
    
    return <WrappedComponent {...props} {...stateToProps} {...dispatchToProps}  />
}

注意:connect 最后返回的是一个props => {}是一个函数式组件

如果直接返回 会报错的

最后我们需要在store里面的state更新的时候渲染页面

	const [ignored, forceUpdate] = useReducer(x => x+1,0)

    useEffect(()=>{
        let unSubscribe = subscribe(()=>{
            forceUpdate()
        })
        return ()=>{
            if(unSubscribe()){
                unSubscribe()
            }
        }
    },[store])

参考的是class 组件的forceUpdate