20-redux在hook中使用

47 阅读1分钟

redux

  • 用于统一管理项目的状态,不过也会使项目的复杂度变高,看这去用

组件

// => 
import React, { useContext, useState, useEffect } from 'react'
import VoteFooter from './VoteFooter'
import VoteMain from './VoteMain'
import ThemeContext from '../ThemeContext';

function Vote() {
  const { store } = useContext(ThemeContext);
  const { supNum, oppNum } = store.getState();
  const [_, setRandom] = useState(0);
  useEffect(() => {
    // => 用于组件的更新
    const unscribe = store.subscribe(() => {
      setRandom(+new Date())
    });
    //=> 清除监听
    return () => unscribe();
  }, [_]);
  return (
    <div>
      <header>
        <h2>React is good</h2>
        <span>{ supNum + oppNum }人</span>
      </header>
      <VoteMain />
      <VoteFooter />
    </div>
  )
}

export default Vote
// => VoteMain.jsx
import React, { useContext } from 'react'
import ThemeContext from '../ThemeContext';

function VoteMain() {
  const { store } = useContext(ThemeContext);
  const { supNum, oppNum } = store.getState();
  return (
    <div>
      <p>支持人数: { supNum }</p>
      <p>反对人数: { oppNum }</p>
    </div>
  )
}

export default VoteMain
// => VoteFooter.jsx
import React, {useContext} from 'react'
import ThemeContext from '../ThemeContext';

function VoteFooter() {
  const { store } = useContext(ThemeContext);
  return (
    <div>
      <button onClick={ () => {
        store.dispatch({
          type: 'VOTE_SUP'
        })} 
      }>支持</button>
      <button onClick={ () => {
        store.dispatch({
          type: 'VOTE_OPP'
        })} 
      }>反对</button>
    </div>
  )
}

export default VoteFooter

上下文对象

// => ThemeContext.js
// 创建上下文对象
import { createContext } from 'react';
const ThemeContext = createContext();
export default ThemeContext;
// => index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import store from './store'
import ThemeContext from './ThemeContext';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <ThemeContext.Provider value={{ store }}>
    <App />
  </ThemeContext.Provider>
);

store

// store/index.js
import { createStore } from 'redux';

// 初始公共状态
let initialState = {
  supNum: 10,
  oppNum: 5
}

// 创建reducer,统一修改公共状态
/**
 * 
 * @param {*} state 容器的公共状态 
 * @param {*} action 每次派发传递进来的行为对象,必须包含type属性(行为标识)
 */
const reducer = function(state = initialState, action) {
  const { type, payload = 1 } = action;
  const newState = {...state};
  switch(type) {
    case 'VOTE_SUP':
      newState.supNum += payload;
      break;
    case 'VOTE_OPP':
      newState.oppNum += payload;
      break;
    default:
      break;
  }
  // return 的值会替换公共状态的值
  return newState;
}

// 创建store
const store = createStore(reducer);
export default store;

图示如下

image.png