使用useReducer和useContext代替redux

本篇文章的受众为使用过redux,并且决定替换掉redux的人群,小白劝退哦

一.useContext使用

1.用途:传值,从父到子,孙,孙孙.. 都可以拿到值

2.用法:

  • 在外面先定义Context
import { createContext } from 'react';

const Context = createContext(null);

export default Context;
  • 在最外层套上<Context.Provider>,这样全局都可以拿到值
/**
 * app容器
 */
import React, { useReducer } from 'react';
import './app.css';
import reducer from './reducers';
import Context from './context';
import TodoList from './components/todoList'
import AddTodo from './components/AddTodo';
import Filter from './components/Filter';

function App() {
  const [state, dispatch] = useReducer(reducer, {
    filter: 'SHOW_ALL',
    todoList: [],
  });
  return (
    //在最外层嵌套
    <Context.Provider value={{ state, dispatch }}>
      <div>做程序员真难</div>
      <TodoList />
      <AddTodo />
      <Filter />
    </Context.Provider>
  );
}

export default App;
  • 子组件就可以拿到值

    import React, { useContext, useEffect } from 'react';
    import Context from '../../context';
    
    //必须是子组件
    const TodoList = () => {
    //state, dispatch就是value里写的,传过来的值
      const { state, dispatch } = useContext(Context);
    };
    
    export default TodoList;
    
          我们看到,通过这种方式,实现了传值问题,只要<Context.Provider>套在最外层,其实在全局都可以拿到值。
    
          我们知道redux是一个全局的状态管理,相当于一个前端的数据存储库,这就肯定包括取值和往里面存值,我们现在通过useContext已经实现了全局取值了,那怎么实现把值放进去呢?
    
          这也是我之前困惑的地方,现在知道了,通过useReducer的dispatch,熟悉redux的小伙伴对于dispatch肯定很熟悉,没错,和redux的dispatch的作用一样。
    

二.useReducer使用

useState的替代方案,它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch方法。

1.用途:通过dispatch,改变值

2.与useState的关系

const [count, setCount] = useState(initialCount);

这是一个useState,count的初始值是initialCount,我们想要改变count的值,只能使用setCount

现在假设有10个useState,我们应该怎样去简化代码?答案就是使用useReducer.

3.用法:

const [state, dispatch] = useReducer(reducer, initialArg, init);

reducer:是一个方法((state, action) => newState),它接受两个参数,state, action,返回一个新的newState

action:就是dispatch里面的内容

新的newState:就是initialArg初始值这样格式的state,也就是你经过dispatch数据更新之后返回的新的初始值格式的值。举例说明:

/**
 * app容器
 */
import React, { useReducer } from 'react';
import './app.css';
import reducer from './reducers';
import Context from './context';
import TodoList from './components/todoList'
import AddTodo from './components/AddTodo';
import Filter from './components/Filter';

function App() {
  const [state, dispatch] = useReducer(reducer, {
    filter: 'SHOW_ALL',
    todoList: [],
  });
  return (
    <Context.Provider value={{ state, dispatch }}>
      <div>做程序员真难</div>
      <TodoList />
      <AddTodo />
      <Filter />
    </Context.Provider>
  );
}

export default App;

上面的reducer是这样的

function filterFun(state, action) {
  switch (action.type) {
    case 'SET_FILTER':
      return action.filter;
    default:
      return state;
  }
}

const todoListFun = (state, action) => {
  switch (action.type) {
    case 'INIT_TODOS':
      return action.todoList;
    case 'TOGGLE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) return { ...todo, isComplete: !todo.isComplete };
        return todo;
      });
    case 'ADD_TODO':
      return [...state, { text: action.text, isComplete: false }];
    default:
      return state;
  }
};

function reducer(state, action) {
//返回值的格式与初始值保持一致
//action:{
     // type: 'INIT_TODOS',
    //  todoList,
  //  }
  return {
    filter: filterFun(state.filter, action),
    todoList: todoListFun(state.todoList, action),
  };
}

export default reducer;

怎样触发dispatch?

dispatch({
      type: 'INIT_TODOS',
      todoList,
    });
    todoList是在业务逻辑中,我们需要获得的值(例如后端拿到的值),我们想把这个值放在中心处理中,就要dispatch进去,我们通过上面的方式,跟redux一致,不做过多解释。

     dispatch执行之后,就会自动触发reducer,dispatch里面对象,会通过action,传到这里,之    后返回一个对应的值,并且会自动渲染,这和redux机制保持一致。

     通过这种方式,就实现了简易的替代redux的使用。
function reducer(state, action) {
//action:{
     // type: 'INIT_TODOS',
    //  todoList,
  //  }
  return {
    filter: filterFun(state.filter, action),
    todoList: todoListFun(state.todoList, action),
  };
}

三.useContext和useReducer结合使用代替redux

useContext传值,useReducer设置值,这样就实现了代替redux

附上源码:

GitHub - LoveVin/todoList-useReducer

原文:用 useReducer 代替 Redux - lovin - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值