react之useReducer+useContext代替redux

1,098 阅读1分钟

当我们使用redux进行数据管理的时候,一般都是在根组件通过Provider的方式引入store,然后在每个子组件中,通过connect的方式使用高阶组件进行连接,这样造成的一个问题是,大量的高阶组件代码冗余度特别高,既然hooks带来了新特性,不如一起来用用看

注意React要16.8.0 以上的版本

  1. src下新建store/index.js
import { createContext, useReducer } from "react"

const initState = {
  count: 60
}

const reducer = (state, action) => {
  switch (action.type) {
    case 'set_count':
      return { ...state, count: action.value}
    default:
      return state
  }
}

export const context = createContext()

const ContextProvider = ({children}) => {
  const [state, dispatch] = useReducer(reducer, initState)
  return (
    <context.Provider value={{state, dispatch}}>
      {children}
    </context.Provider>
  )
}

export default ContextProvider
  1. App.js
import Router from './router'
import ContextProvider from './store'

function App() {
  return (
    <ContextProvider>
      <Router />
    </ContextProvider>
  );
}

export default App;
  1. 父组件展示状态
import { Outlet } from 'react-router-dom'
import { context } from '../../store'
import { useContext } from 'react';

const Home = () => {
  const { state: {count} } = useContext(context)
  return (
    <div>
      <h2>home parent</h2>
      <h4>count: {count}</h4>
      <Outlet />
    </div>
  );
};

export default Home
  1. 子组件修改状态
import { context } from '../../store'
import { useContext } from 'react';

const Test = () => {
  const { state: { count }, dispatch } = useContext(context)
  const addFn = () => {
    dispatch({ type: 'set_count', value: count + 1 })
  }
  const reduceFn = () => {
    dispatch({ type: 'set_count', value: count - 1 })
  }
  return (
    <div>
      <h4>
        test children
      </h4>
      <button onClick={reduceFn}>-1</button>
      <button onClick={addFn}>+1</button>
    </div>
  );
};

export default Test