redux原理

理解原理的关键点:
1、createStore 函数返回 getState,subscribe,dispatch三个参数。
2、subscribe负责收集connect内部的更新方法forceComponentUpdateDispatch,并设置进去lisenters。
3、key就是这里
在这里插入图片描述
4、观察函数变化 bindActionCreators函数变化
4.1:传递两个函数进去bindActionCreator,然后把其中一个函数放在另一个函数里面执行,这有点难理解,因为日常写法很少这么写的。
4.2:将 (…args) => dispatch(actionCreator(…args)); 转化成 (…args) => dispatch({ type: ‘ADD’ });
4.3:然后在bindActionCreator里面返回 { add: (…args) => dispatch({ type: ‘ADD’ }) }

context.js
下面展示一些 内联代码片

import React, { Component, useLayoutEffect, useReducer, useContext } from 'react' 
export const ReactReduxContext = React.createContext();

App.js

import Home from './component/home' 
import React, { Component } from 'react'; 
import {ReactReduxContext} from './component/context'; 
import store from './component/redux'; 
class App extends Component { 
    render() { 
        return ( <div> 
                    <ReactReduxContext.Provider value={store}> 
                        <Home /> 
                    </ReactReduxContext.Provider> 
                 </div> ); 
    } 
} 
export default App;

redux.js

import React, { Component, useLayoutEffect, useReducer, useContext } from 'react'
import {ReactReduxContext} from './context';
// ------------------------------------------------------------------------------
export const connect = (mapStateToProps = (state) => state, mapDispatchToProps) =>
 (WrappedComponent) => (props) => {
  const store = useContext(ReactReduxContext);
  const { getState, dispatch, subscribe } = store;
  console.log('store1', store)
  console.log('getState', getState)
  // mapStateToProps 是在使用 connect 时传入的第一个参数,
  // getState 获取到 state 到值,然后传递给 mapStateToProps 使用
  // mapStateToProps 执行完成后返回需要传递给组件的 stateProps
  const stateProps = mapStateToProps(getState());

  // connect 的第二个参数 mapDispatchToProps 可以是对象或者函数
  let dispatchProps;
  if (typeof mapDispatchToProps === 'object') {
    // 如果 mapDispatchToProps 是一个对象,则使用 bindActionCreators 将该对象包装成可以直接调用的函数对象
    dispatchProps = bindActionCreators(mapDispatchToProps, dispatch);
  } else if (typeof mapDispatchToProps === 'function') {
    // 如果 mapDispatchToProps 是一个函数,则调用函数并传入 dispatch
    dispatchProps = mapDispatchToProps(dispatch);
  } else {
    // 默认传递 dispatch
    dispatchProps = { dispatch };
  }
    
  function storeStateUpdatesReducer(state, action) {
    return state + 1;
  }
  // 使用 useReducer 实现强制更新页面
  // useReducer 返回的数组包含两个项 state, dispatch],调用 dispatch 返回新的 state 时,组件会重新渲染
  const [state, forceComponentUpdateDispatch] = useReducer(
    storeStateUpdatesReducer,
    0
  );

  useLayoutEffect(() => {
    // 订阅 store 中数据更新,强制刷新页面
    const ubsubscribe = subscribe(() => {
      forceComponentUpdateDispatch();
    });
    return () => {
      // 卸载组件取消订阅
      ubsubscribe && ubsubscribe();
    };
  }, [store]);

  // 将需要“连接”的组件返回,并传递给组件需要的数据
  return <WrappedComponent {...props} {...stateProps} {...dispatchProps} />;  
};
// ------------------------------------------------------------------------------
function bindActionCreator(actionCreator, dispatch) {
  return (...args) => dispatch(actionCreator(...args));
}

function bindActionCreators(actionCreators, dispatch) {
  if (typeof actionCreators === 'function') {
    return bindActionCreator(actionCreators, dispatch)
  }
  const boundActionCreators = {};
  for (let key in actionCreators) {
    const actionCreator = actionCreators[key]
    if (typeof actionCreator === 'function') {
      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
    }
  }
  return boundActionCreators;
}
// ------------------------------------------------------------------------------
function createStore(reducer) {
  let currentState;
  let lisenters = [];

  function getState() {
    return currentState;
  }

  function subscribe(listener) {
    lisenters.push(listener);

    // return function unsubscribe() {
    //   const index = lisenters.indexOf(lisenter);
    //   lisenters.splice(index, 1);
    // };
  }

  function dispatch(action) {
    // 调用 reducer 函数,修改当前的 state
    currentState = reducer(currentState, action)
    // 循环调用回调函数
    for (let i = 0; i < lisenters.length; i++) {
      const lisenter = lisenters[i];
      lisenter()
    }
  }

  return {
    getState,
    subscribe,
    dispatch,
  }
}

const reducer = (state = 0, action) => {
  console.log('调用到reducer');
  switch (action.type) {
    case 'ADD':
      return state + 1;
    case 'MINUS':
      return state - 1;
    default:
      return state;
  }
};

const store = createStore(reducer);

export default store;

home.js

import React, { Component } from 'react';
import { connect } from './redux';

class Home extends Component {
  add = () => {
    this.props.dispatch({ type: 'ADD' });
  };

  minus = () => {
    this.props.dispatch({ type: 'MINUS' });
  };

  asyncAdd = () => {
    this.props.dispatch((dispatch) => {
      setTimeout(() => {
        dispatch({ type: 'ADD' });
      }, 1000);
    });
  };

  render() {
    return (
      <div>
        <div>count: {this.props.count}</div>
        {/* <button onClick={this.add}>add</button> */}
        <button onClick={this.props.add}>add</button>
        <button onClick={this.minus}>minus</button>
        <button onClick={this.asyncAdd}>asyncAdd</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({ count: state });
const mapDispatchToProps = {
  add: () => ({ type: 'ADD' }),
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值