React Hooks 之 useReducer useRef useContext和useMemo 的用法

社会主义新天地 提交于 2020-12-19 10:11:56


之前文章中我们有讲到的 useState hook 和 useEffect hook 的一些概念和基本用法,趁着周末空闲时间,我们一起来看看 React 为我们提供的其他 hooks 的一些基本使用吧。

useReducer

useReducer hook 接收两个参数,第一个是参数是一个函数(这是一个 reducer函数:它接收两个参数 state 和 action,它会根据 action 类型返回一个新的state),第二个参数是一个初始状态(intialState)。语法如下:

      
        
      
      
  1. const [newState, dispatch] = useReducer((state, action) => {

  2. //根据派发出去的 action 类型,返回一个 newState

  3. }, intialState)

看一个例子:

      
        
      
      
  1. const Counter = () => {

  2. //count对应 reducer 返回的nweState

  3. //dipatch 负责派发一个 action(动作)

  4. //action是一个具有 type 属性的一个javascript对象

  5. const [count, dispatch] = useReducer((state, action) => {

  6. switch (action.type) {

  7. case 'add':

  8. return state + 1;

  9. case 'sub':

  10. return state - 1;

  11. default:

  12. return state;

  13. }

  14. }, 0)

  15. return (

  16. <div>

  17. <div>CountSum: {count}</div>

  18. <button onClick={() => dispatch({ type: 'add' })}>Add</button>

  19. <button onClick={() => dispatch({ type: 'sub' })}>Substract</button>

  20. </div>

  21. )

  22. }


  23. export default Counter;

useReducer hook 的流程可以总结为:

事件发生 -->调度方法(dispatch)派发一个动作(action) --> reducer 根据派发的动作类型(action.type)返回一个新的状态(newState)

useRef hook

Refs 用于访问在 render 呈现的 DOM 或 React 元素。在以前的 React 版本中使用refs的标准方法是这样的:

      
        
      
      
  1. //16.3提供

  2. class RefHook extends React.Component {

  3. constructor(props) {

  4. super(props);

  5. //创建ref

  6. this.myRef = React.createRef();

  7. }


  8. render() {

  9. return <div ref={this.myRef}></div>

  10. }

  11. }

  12. export default RefHook;

现在可以使用 useRef hook:

      
        
      
      
  1. //16.8提供

  2. function RefHook() {


  3. const myRef = useRef();

  4. function handleChange() {

  5. console.log(myRef);

  6. }


  7. return <div onChange={handleChange} ref={myRef}></div>

  8. }


  9. export default RefHook;

useContext hook 

Context API 解决了 React 最大的问题之一就是 props 多层组件传递。在以前的版本中:

      
        
      
      
  1. const ThemeContext = React.createContext();

  2. function ContextComponent() {

  3. return (

  4. <ThemeContext.Provider value="dark">

  5. <ThemeButton />

  6. </ThemeContext.Provider>

  7. )

  8. }


  9. function ThemeButton() {

  10. return (

  11. <ThemeContext.Consumer>

  12. {(theme) => <div> This is theme: {theme} </div>}

  13. </ThemeContext.Consumer>

  14. )

  15. }


  16. export default ContextComponent;

useContext hook 提供了使用上下文的很多优化的方式。

      
        
      
      
  1. import React, { useContext } from 'react';


  2. const ThemeContext = React.createContext();

  3. function ContextComponent() {

  4. return (

  5. <ThemeContext.Provider value="dark">

  6. <Theme />

  7. </ThemeContext.Provider>

  8. )

  9. }


  10. function Theme() {

  11. const theme = useContext(ThemeContext);

  12. return (

  13. <div> This is theme: {theme} </div>

  14. )

  15. }


  16. export default ContextComponent;

useMemo hook

React有一个名为 useMemo 的钩子,它让我们记忆复杂而昂贵的函数,这样我们就可以避免每次重复的渲染。

它是采用了 Memoization 思想  它是 JavaScript 中的一种技术,通过缓存结果并在下一个操作中重新使用缓存来加速查找费时的操作。

比方说,我们必须编写一个函数来查找给定数字的平方。

      
        
      
      
  1. const calc = num => {

  2. return num * num;

  3. }

  4. calc(4); // 16

  5. calc(5); // 25

  6. calc(35); // 1225

  7. calc(35); // 1225

  8. calc(5); // 25

  9. calc(35); // 36

我们计算了两次 35 的平方,这还好因为它不是什么密集的操作,如果是非常耗时的操作,就会变得很昂。采用  Memoization  可以这么做:

      
        
      
      
  1. const cache = {};

  2. const calc = num => {

  3. let result = cache[num];

  4. if(!result) {

  5. result = num * num;

  6. cache[num] = result;

  7. }

  8. return result;

  9. }

  10. calc(4);

  11. calc(5);

  12. calc(35); //1225

  13. calc(35); //1225

  14. console.log(cache); // {4: 16, 5: 25, 35: 1225}

从上边的例子中我们可以看到,当我们再计算 35 的平方时,不需要重新计算,而直接从缓存中选择值即可,提高了程序的性能。

在 React 中,有些时候我们不想每次都重新渲染组件,基于 Memoization 思想 useMemo hook 就是负责记忆相应的组件,只有在数据发生变化时组件才会重新渲染。

      
        
      
      
  1. function Parent({ a, b }) {

  2. // 当 a b 有一个发生变化时 才重新渲染

  3. const child1 = useMemo(() => <Child1 a={a} b={b}/>, [a, b]);

  4. // 当 b 发生变化时 才重新渲染

  5. const child2 = useMemo(() => <Child2 b={b} />, [a, b]);

  6. return (

  7. <>

  8. { child1 }

  9. { child2 }

  10. </>

  11. )

  12. }


如果公众号里的文章对您有所帮助,麻烦大家点击关注并帮助分享下,在这里谢谢大家啦。


一扫


注我


本文分享自微信公众号 - 像素摇摆(pxDance)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!