返回顶部
首页 > 资讯 > 前端开发 > JavaScript >useReducer createContext代替Redux原理示例解析
  • 552
分享到

useReducer createContext代替Redux原理示例解析

useReducer createContext代替ReduxuseReducer createContext 2022-11-13 19:11:53 552人浏览 独家记忆
摘要

目录前言采用React-redux实现采用react hooks模拟redux实现异步action总结 前言 最近看到很多采用useReducer + createContext 实

前言

最近看到很多采用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的资料请关注编程网其它相关文章!

--结束END--

本文标题: useReducer createContext代替Redux原理示例解析

本文链接: https://lsjlt.com/news/170638.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作