文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React useMemo和useCallback的使用场景

2024-04-02 19:55

关注

useMemo

我们知道当父组件发生重新渲染时,其所有(状态、局部变量等)都是新的。一旦子组件依赖于父组件的某一个对象变量,那么无论对象是否发生变化,子组件拿到的都是新的对象,从而使子组件对应的 diff 失效,依旧会重新执行该部分逻辑。在下面的例子中,我们的副作用依赖项中包含了父组件传入的对象参数,每次父组件发生更新时,都会触发数据请求。


function Info({
  style,
}) {
  console.log('Info 发生渲染');

  useEffect(() => {
    console.log('重新加载数据'); // 每次发生重新渲染时,都会重新加载数据
  }, [style]);

  return (
    <p style={style}>
      这是 Info 里的文字
    </p>
  );
}

function Page() {
  console.log('Page 发生渲染');

  const [count, setCount] = useState(0);
  const style = { color: 'red' };

  // 计数器 +1 时,引发 Page 的重新渲染,进而引发 Info 的重新渲染
  return (
    <div>
      <h4>计数值为:{count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <Info style={style} />
    </div>
  );
}

React Hooks 给我们提供了解决方案,useMemo 允许我们缓存传入的对象,仅当依赖项发生变化时,才重新计算并更新相应的对象。


function Page() {
  console.log('Page 发生渲染');

  const [color] = useState('red');
  const [count, setCount] = useState(0);
  const style = useMemo(() => ({ color }), [color]); // 只有 color 发生实质性改变时,style 才会变化

  // 计数器 +1 时,引发 Page 的重新渲染,进而引发 Info 的重新渲染
  // 但是由于 style 缓存了,因此不会触发 Info 内的数据重新加载
  return (
    <div>
      <h4>计数值为:{count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <Info style={style} />
    </div>
  );
}

useCallback

React Hooks 在数据流上带来的变化有两点:一是支持更友好的使用 context 进行状态管理,避免层级过多时向中间层承载无关参数;二是允许函数参与到数据流中,避免向下层组件传入多余的参数。

useContext 作为 hooks 的核心模块之一,可以获取到传入 context 的当前值,以此达到跨层通信的目的。React 官网有着详细的介绍,需要关注的是一旦 context 值发生改变,所有使用了该 context 的组件都会重新渲染。为了避免无关的组件重绘,我们需要合理的构建 context ,比如从第一节提到的新思维模式出发,按状态的相关度组织 context,将相关状态存储在同一个 context 中。

在过去,如果父子组件用到同一个数据请求方法 getData ,而该方法又依赖于上层传入的 query 值时,通常需要将 query 和 getData 方法一起传递给子组件,子组件通过判断 query 值来决定是否重新执行 getData。


class Parent extends React.Component {
   state = {
    query: 'keyword',
  }

  getData() {
    const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${this.state.query}`;
    // 请求数据...
    console.log(`请求路径为:${url}`);
  }

  render() {
    return (
      // 传递了一个子组件不渲染的 query 值
      <Child getData={this.getData} query={this.state.query} />
    );
  }
}

class Child extends React.Component {
  componentDidMount() {
    this.props.getData();
  }

  componentDidUpdate(prevProps) {
    // if (prevProps.getData !== this.props.getData) { // 该条件始终为 true
    //   this.props.getData();
    // }
    if (prevProps.query !== this.props.query) { // 只能借助 query 值来做判断
      this.props.getData();
    }
  }

  render() {
    return (
      // ...
    );
  }
}

在 React Hooks 中 useCallback 支持我们缓存某一函数,当且仅当依赖项发生变化时,才更新该函数。这使得我们可以在子组件中配合 useEffect ,实现按需加载。通过 hooks 的配合,使得函数不再仅仅是一个方法,而是可以作为一个值参与到应用的数据流中。


function Parent() {
  const [count, setCount] = useState(0);
  const [query, setQuery] = useState('keyword');

  const getData = useCallback(() => {
    const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${query}`;
    // 请求数据...
    console.log(`请求路径为:${url}`);
  }, [query]);  // 当且仅当 query 改变时 getData 才更新

  // 计数值的变化并不会引起 Child 重新请求数据
  return (
    <>
      <h4>计数值为:{count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <input onChange={(e) => {setQuery(e.target.value)}} />
      <Child getData={getData} />
    </>
  );
}

function Child({
  getData
}) {
  useEffect(() => {
    getData();
  }, [getData]); // 函数可以作为依赖项参与到数据流中

  return (
    // ...
  );
}

以上就是React useMemo和useCallback的使用场景的详细内容,更多关于React useMemo和useCallback的使用的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯