使用react-redux 怎们能不了解原理,彻底了解原理和单纯的使用,应该不是一个级别的选手吧
redux原理实现
-
简单的redux
// 根据我们使用redux的用法 ,开始是createStore然后createStore中有getState、dispatch、subscribe // createStore 有两个参数 第一个reducer 第二个参数中间件 (增强) import React from "react"; export function createStore(reducer, enhancer) { let currentState ; //初始状态 可以是对象或者什么都可以,因为使用时会给出初始值 let currentListeners = []; //每次函数的修改都要触发组件的变化 ,所以要有监听器 function getState() { // 定义getState方法,getState()返回当前的state树,它与 store 的最后一个 reducer 返回值相同。 return currentState; } function subscribe(listener) { //定义我们监听的时候使用的方法 currentListeners.push(listener) // 将我们需要监听的组件传递进来,push到currentListeners数组中 } function dispatch(action) { //定义我们的dispatch方法 使用dispatch会传递一个action参数 currentState = reducer(currentState,action); // reducer 中有两个参数 像这样 counterReducer = (state=0,action)=>{ } reducer返回的新的state currentListeners.forEach(value => value()); // 每次dispatch都执行一下 所有 subscribe里的内容 ,比如index.js中 每一次dispatch都执行render= ()=>{}这个方法 // const render =()=>{ // ReactDOM.render( // <App />, // document.getElementById('root') // ); // }; // render(); // store.subscribe(render); return action } dispatch({type:'@IMOOC/WONIU-REDUX'}); //手动先dispatch ,让它第一次dispatch命中默认初始值dispatch,不然不会有初始值 return {getState,subscribe,dispatch} } 复制代码
-
react-redux
-
Provider
Provider 模块功能并不复杂 ,需要实现一下两点
- 在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
- 接收Redux的store作为props,通过context对象传递给子孙组件上的connect
import React,{Component} from 'react' import PropTypes from 'prop-types' // prop-types就是对react组件中props对象中的变量进行类型检测的,因为props是react数据流的管道,我们通过prop-types就可以轻松监控react里大多数据的变量类型 export class Provider extends Component{ static childContextTypes = { // 设置childContext 状态值类型 store: PropTypes.object }; getChildContext(){ // 设置childContext,设置完了这样所有的子元素都能取到 return {store:this.store} } constructor(props, context){ super(props, context); this.store = props.store } render(){ return this.props.children // this.props.children是react内置在this.props上的对象,用于获取当前组件的所有子组件 } } // Provider初始化时,获取到props中的store对象; // 将外部的store对象放入context对象中,使子孙组件上的connect可以直接访问到context对象中的store。 // context可以使子孙组件直接获取父级组件中的数据或方法,而无需一层一层通过props向下传递。 // context对象相当于一个独立的空间,父组件通过getChildContext()向该空间内写值;定义了contextTypes验证的子孙组件可以通过this.context.xxx,从context对象中读取xxx字段的值。 复制代码
-
connect
//添加监听对象,并尝试通过 props 将状态传递给子组件 const connect = (mapStateToProps,mapDispatchToProps)=>{ //返回一个函数 return WrappedComponent=>{ return class ConnectComp extends Component{ static contextTypes = { store:PropTypes.object }; //获取context constructor(props,context){ super(props, context) this.state = { props:{} // 手动定义一个state } } componentDidMount(){ const {store} = this.context store.subscribe(()=>this.update()) // 每次dispatch(更新)都会执行一下subscribe 里边的 this.update() // } update(){ const {store} = this.context; const stateProps =mapStateToProps(store.getState()) const dispatchProps = bindActionCreators(mapDispatchToProps,store.dispatch) //作用是将单个或多个ActionCreator转化为dispatch(action)的函数集合形式。 //将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容 ,其实就是把多个action还是用dispatch调用 this.setState({ props:{ ...this.state.props, ...stateProps, ...dispatchProps } }) } render() { return <WrappedComponent {...this.state.props}></WrappedComponent> // 这个WrappedComponent也就是我们的使用的App,这样的connect(mapStateToProps,mapDispatchToProps)(App) // 使用connect组件的时候 我们的state add方法等等都到了props之上,就是通过这实现的 } } } } 复制代码
-
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END