useReducer createContext代替Redux原理示例解析

 更新时间:2022年11月03日 08:33:45   作者:冯心心爱吃肉  
这篇文章主要为大家介绍了useReducer createContext代替Redux原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

最近看到很多采用useReducer + createContext 实现一个简易的redux的方案,今天亲自试了一下,发现还是会有一些区别的。

采用react-redux实现

这里使用react-redux 实现一个简单的状态管理例子。

App.jsx根组件

import React from 'react';
import { Button } from './Button';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import A from './a';
export default function ButtonDemo1() {
  const reducer = (state, action) => {
    const { name, theme } = state;
    switch (action.type) {
      case 'UPDATENAME':
        return {
          ...state,
          name: `${name} + 1`,
        };
      case 'UPDATETHEME':
        return {
          ...state,
          theme: theme === 'dark' ? 'light' : 'dark',
        };
      default:
        return state;
    }
  };
  const store = createStore(reducer, {
    name: 'fx',
    theme: 'dark',
  });
  return (
    <Provider store={store}>
      <div>
        <Button />
        <A />
      </div>
    </Provider>
  );
}

A组件用于dispatch和接收store

A.jsx

import React, { useContext } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { reduxContent } from './index1';
export default function A() {
  const dispatch = useDispatch();
  return (
    <div onClick={() => dispatch({ type: 'UPDATENAME' })}>
      {useSelector((state) => state.name)}
    </div>
  );
}

效果如图:

可以看到,Button组件未使用redux store,因此正常渲染了一次。

采用react hooks模拟redux实现

这里采用useReducer + createContext 模拟实现一个redux

App.jsx

import React, { useReducer, createContext } from 'react';
import { Button } from 'concis';
import A from './a';
export const reduxContent = createContext({});
export default function ButtonDemo1() {
  const reducer = (state, action) => {
    const { name, theme } = state;
    switch (action.type) {
      case 'UPDATENAME':
        return {
          ...state,
          name: `${name} + 1`,
        };
      case 'UPDATETHEME':
        return {
          ...state,
          theme: theme === 'dark' ? 'light' : 'dark',
        };
      default:
        return state;
    }
  };
  const [redux, dispatch] = useReducer(reducer, {
    name: 'fx',
    theme: 'dark',
  });
  return (
    <reduxContent.Provider value={{ redux, dispatch }}>
        <Button />
        <A />
    </reduxContent.Provider>
  );
}

A.jsx

import React, { useContext } from 'react';
import { reduxContent } from './index1';
export default function A() {
  const { redux, dispatch } = useContext(reduxContent);
  return (
    <div onClick={() => dispatch({ type: 'UPDATENAME' })}>
      {redux.name}
    </div>
  );
}

同样,子组件也可以对store中的状态进行getdispatch,但是会出现这样的问题:

可以看到,Button组件并没有使用store中的内容,但是会随着A组件一起跟着重新渲染,原因其实就是采用这种方式store是存储在根组件的,根组件状态发生了变化(useReducer),子组件跟着一起重新渲染了,因此解决这个问题的思路其实和解决常规的子组件没变化一起被更新的思路是一样的。

可以采用 useMemo限制 + memo 浅比较。

因此只需要在App.jsx中这样修改:

 const renderButton = React.useMemo(() => {
    return <Button />;
  }, []);
  return (
    <reduxContent.Provider value={{ redux, dispatch }}>
      <div style={{ display: 'flex', flexWrap: 'wrap' }}>
        {renderButton}
        <A />
      </div>
    </reduxContent.Provider>
  );
}

Button.jsx

const Button = (props) => {
    ......
})
export default React.memo(Button);

异步action

同样,如果需要异步dispatch的话,简单的场景其实单纯使用异步操作就可以完成,但是在复杂的场景下很难对于异步流进行管理和维护,这时就需要借助redux中间件了,类似redux-thunkredux-saga,而这也是使用hooks无法实现的,无法处理副作用,拦截action去更好的reducer

总结

当然,并不是说采用react hooks所实现的状态管理方式没有好处,这样可以更加贴合react原生,采用react自身所提供的hook,并且可以减少项目中的redux各种实例、减少代码体积,对于小型项目或是不需要很多全局状态的项目,这种方式确实是不错的选择。但是redux仍然是大型项目中最可靠的保障存在。

以上就是useReducer createContext代替Redux原理示例解析的详细内容,更多关于useReducer createContext代替Redux的资料请关注脚本之家其它相关文章!

相关文章

  • React的生命周期函数初始挂载更新移除详解

    React的生命周期函数初始挂载更新移除详解

    这篇文章主要为大家介绍了React的生命周期函数初始挂载更新移除详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • react简单实现防抖和节流

    react简单实现防抖和节流

    在日常开发中,我们经常会有防抖和节流的需要,可以减小服务器端压力,提升用户体验,本文就详细的介绍了react简单实现防抖和节流,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • React浅析Fragments使用方法

    React浅析Fragments使用方法

    这篇文章主要介绍了React Fragments使用方法,关于react Fragments,React中一个常见模式是为一个组件返回多个元素。Fragments 可以让你聚合一个子元素列表,并且不在DOM中增加额外节点
    2022-12-12
  • React路由跳转的实现示例

    React路由跳转的实现示例

    在React中,可以使用多种方法进行路由跳转,本文主要介绍了React路由跳转的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 用React-Native+Mobx做一个迷你水果商城APP(附源码)

    用React-Native+Mobx做一个迷你水果商城APP(附源码)

    这篇文章主要介绍了用React-Native+Mobx做一个迷你水果商城APP,功能需要的朋友可以参考下
    2017-12-12
  • react native 获取地理位置的方法示例

    react native 获取地理位置的方法示例

    这篇文章主要介绍了react native 获取地理位置的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • React找不到模块“./index.module.scss”或其相应的类型声明及解决方法

    React找不到模块“./index.module.scss”或其相应的类型声明及解决方法

    这篇文章主要介绍了React找不到模块“./index.module.scss”或其相应的类型声明及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • react使用antd-design中select不能及时刷新问题及解决

    react使用antd-design中select不能及时刷新问题及解决

    这篇文章主要介绍了react使用antd-design中select不能及时刷新问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 详解React Native 采用Fetch方式发送跨域POST请求

    详解React Native 采用Fetch方式发送跨域POST请求

    这篇文章主要介绍了详解React Native 采用Fetch方式发送跨域POST请求,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 基于React实现搜索GitHub用户功能

    基于React实现搜索GitHub用户功能

    在本篇博客中,我们将介绍如何在 React 应用中搜索 GitHub 用户并显示他们的信息,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02

最新评论