【前端知识】React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)

这篇具有很好参考价值的文章主要介绍了【前端知识】React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)

一、useContext的使用

在类组件开发时,我们通过 类名.contextType = MyContext的方式,在类中获取context,多个Context或者在函数式组件中通过MyContext.Consumer方式共享context:

import React, { memo } from 'react'
import { UserContext, ThemeContext } from './context'

export default memo(function App() {

// 使用Context

  return (
    <div>
      <UserContext.Consumer>
        {
          value => {
            return (
              <h2>
                <ThemeContext.Consumer>
                  {
                    value => {
                      <span></span>
                    }
                  }
                </ThemeContext.Consumer>
              </h2>
            )
          }
        }
      </UserContext.Consumer>
    </div>
  )
})

可以看到,当我们需要使用多个Context时,存在大量繁琐的嵌套代码;而Context Hook能够让我们通过Hook直接获取某个Context的值,如下:

import React, { memo, useContext } from "react";
import { ThemeContext, UserContext } from "./context";

export default memo(function App() {
  // 使用Context
  const user = useContext(UserContext);
  const theme = useContext(ThemeContext);

  return (
    <div>
      <h2>
        User: {user.name} - {user.age}
      </h2>
      <h2>
        Theme: {theme.color} - {theme.size}
      </h2>
    </div>
  );
});

可以看到,Context Hook仅用了两行代码就替代了上面繁杂的嵌套代码,十分高效简洁。

二、useReducer的使用

useReducer是useState的一种替代方案,当state的处理逻辑比较复杂,可以使用useReducer来进行拆分,或者当修改state时需要依赖之前的state时,也可以使用useReducer。

useReducer使用的场景非常少,通常用于需要统一管理、修改多个数据的场景。例如,当我们需要对多个数据进行统一处理时,若采用useState,则需要多次定义,而reducer可以对其进行统一定义、修改:

import React, { memo, useReducer, useState } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { ...state, counter: state.counter + 1 };
    case "decrement":
      return { ...state, counter: state.counter - 1 };
    case "add_number":
      return { ...state, counter: state.counter + action.num };
    case "sub_number":
      return { ...state, counter: state.counter - action.num };
    default:
      return state;
  }
}

export default memo(function App() {
  // const [count, setCount] = useState(0);
  // const [user, setUser] = useState(0);
  // const [list, setList] = useState(0);

  const [state, dispatch] = useReducer(reducer, {
    counter: 0,
    user: {},
    list: [],
  });

  return (
    <div>
      {/* <h2>当前计数:{count}</h2>
      <button onClick={(e) => setCount(count + 1)}>+1</button>
      <button onClick={(e) => setCount(count - 1)}>-1</button>
      <button onClick={(e) => setCount(count + 5)}>+5</button>
      <button onClick={(e) => setCount(count - 5)}>-5</button>
      <button onClick={(e) => setCount(count + 100)}>+100</button> */}

      <h2>当前计数:{state.counter}</h2>
      <button onClick={(e) => dispatch({ type: "increment" })}>+1</button>
      <button onClick={(e) => dispatch({ type: "decrement" })}>-1</button>
      <button onClick={(e) => dispatch({ type: "add_number", num: 5 })}>
        +5
      </button>
      <button onClick={(e) => dispatch({ type: "sub_number", num: 5 })}>
        -5
      </button>
      <button onClick={(e) => dispatch({ type: "add_number", num: 100 })}>
        +100
      </button>
    </div>
  );
});

三、useCallback的使用

useCallback实际的目的是为了进行性能优化,useCallback会返回一个函数的memoized(记忆的)值。在依赖不变的情况下,多次定义的时候,返回的值时相同的。

useCallback的性能优化:

  1. 当需要将一个函数传递给子组件时,可使用useCallback进行优化,将优化之后的函数,传递给子组件

    import React, { memo, useCallback, useState } from "react";
    
    const HYIncrement = memo(function (props) {
      const { increment } = props;
    
      console.log("HYIncrement被渲染");
    
      return (
        <div>
          <button onClick={increment}>increment + 1</button>
        </div>
      );
    });
    
    export default memo(function App() {
      const [count, setCount] = useState(0);
      const [message, setMessage] = useState("hello");
    
      // 使用useCallback
      const increment = useCallback(
        function () {
          setCount(count + 1);
        },
        [count]
      );
    
      // 普通函数
      // const increment = () => {
      //   setCount(count + 1);
      // };
    
      return (
        <div>
          <h2>计数:{count}</h2>
          <button onClick={increment}>+1</button>
    
          <HYIncrement increment={increment} />
    
          <h2>message:{message}</h2>
          <button onClick={(e) => setMessage("world")}>修改 message</button>
        </div>
      );
    });
    
    
  2. 进一步优化

    当count发生改变时,也使用同一个函数文章来源地址https://www.toymoban.com/news/detail-622976.html

      // 做法一:将count依赖移除掉,缺点:存在闭包陷阱,不依赖count后setCount每次拿到的count并非最新的count
      // const increment = useCallback(function foo() {
      //   console.log("increment");
      //   setCount(count + 1);
      // }, []);
    
      // 做法二:利用useRef,在组件多次渲染时,返回同一个值
      const countRef = useRef();
      countRef.current = count;
      const increment = useCallback(
        function foo() {
          console.log("increment");
          setCount(countRef.current + 1);
        },
        []
      );
    

到了这里,关于【前端知识】React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【前端知识】React 基础巩固(四十一)——手动路由跳转、参数传递及路由配置

    利用 useNavigate 封装一个 withRouter(hoc/with_router.js) 添加到hoc/index.js文件中 利用withRouter,拦截Home组件,实现手动跳转路由 路由参数传递包括:1.动态路由传参;2.查询字符串传参 改造withRouter,通过 useParams() 和 useSearchParams() 来接收两种参数传递: 在界面中,通过params来接收

    2024年02月14日
    浏览(44)
  • 【前端知识】React 基础巩固(十四)——JSX 的转换过程和声明式编程

    jsx 仅仅只是 React.createElement(component, props, …children)函数的语法糖 所有的 jsx 最终都会被转换成 React.createElement 的函数调用 createElement 需要传递三个参数: type 当前 ReactElement 的类型 如果是标签元素,那么就使用字符串表示 “div” 如果是组件元素,那么就直接使用组件的名称

    2024年02月09日
    浏览(74)
  • 【前端知识】React 基础巩固(三十四)——组件中的异步操作及优化

    通过组件的生命周期来完成网络请求,网络请求的异步代码直接放在组件中 通过redux来管理异步网络请求 在store中引入中间件 redux-thunk 构建 fetchHomeMultidataAction ,将原本在组件中的异步请求代码放入到actionCreators.js中 改写原来的category.jsx,派发异步请求的dispatch 查看运行结果

    2024年02月15日
    浏览(57)
  • 【前端知识】React 基础巩固(十三)——列表渲染

    在 React 中没有像 Vue 模块语法中的 v-for 指令,而是需要我们通过 JS 代码的方式组织数据,转成 JSX 在 React 中,展示列表最多的方式就是使用数组的 map 高阶函数 在展示数组前,有时会进行一些处理 过滤一些内容(filter 函数) 截取数组中的一部分内容(slice 函数) 列表中的

    2024年02月10日
    浏览(44)
  • 【前端知识】React 基础巩固(二十八)——StrictMode

    StrictMode 是一个用来突出显示应用程序中潜在问题的工具 与 Fragment 一样,StrictMode 不会渲染任何可见的 UI 为后代出发额外的检测和警告 严格模式检查仅在开发模式下运行,不影响生产构建 严格模式检查什么? 识别不安全的生命周期 使用过时的 ref API 检查意外的副作用 组件

    2024年02月16日
    浏览(43)
  • 【前端知识】React 基础巩固(二十七)——Fragment

    Fragment 允许将子列表分组,而无需向 DOM 添加额外节点 可以采用语法糖 / 来替代 Fragment,但在需要添加 key 的场景下不能使用此短语 查看Fragment应用后的效果

    2024年02月16日
    浏览(49)
  • 【前端知识】React基础巩固(二)——JSX注意点

    createElement存在的问题: 繁琐不简洁 不直观,无法一眼看出所描述的结构 不优雅,开发体验不好 JSX 简介:JSX 是 JavaScript XML 的简写,表示了在JS代码中写XML(HTML)格式的代码 优势:声明式语法更加直观,与HTML结构相同,降低学习成本,提高开发效率 JSX 是 react 的核心内容‘

    2024年02月09日
    浏览(63)
  • 【前端知识】React 基础巩固(二十三)——React 性能优化 SCU相关

    React 的渲染流程 JSX - 虚拟 DOM - 真实 DOM React 的更新流程 props/state 改变 - render函数重新执行 - 产生新的DOM树 - 新旧DOM树进行diff - 计算出差异进行更新 - 更新到真实的DOM React 在 props 或 state 发生改变时,会调用 React 的 render 方法,会创建一颗不同的树 React 需要基于这两颗不同的

    2024年02月15日
    浏览(62)
  • 【前端知识】React 基础巩固(三十五)——ReduxToolKit (RTK)

    Redux Tool Kit (RTK)是官方推荐的编写Redux逻辑的方法,旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题。 RTK的核心API主要有如下几个: configureStore:包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的slice reducer,添加你提供的任何Redux中间件

    2024年02月15日
    浏览(56)
  • 【前端知识】React 基础巩固(七)——JSX 的基本语法

    JSX 是一种 JS 的语法扩展(extension),也可以称之为 JavaScript XML,因为看起来就是一段 XML 语法 它用于描述我们的 UI 界面,并且其可以和 JS 融合在一起使用 它不同于 Vue 中的模块语法,不需要专门学习模块语法中的指令 React 认为 渲染逻辑 本质上与 其他UI逻辑 存在内在耦合

    2024年02月10日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包