标签: react-usememo

将 useMemo/React.memo 用于一组对象以防止在编辑其中一个对象后重新渲染的最佳方法?

我正在努力解决我的 React 应用程序的性能问题。例如,我有一个卡片列表,您可以添加像 Facebook 一样的卡片。一旦其中一个子项更新,所有列表都会重新渲染,所以在这里我尝试使用 useMemo 或 React.memo。我以为我可以使用 React.memo 作为卡片组件,但没有成功。不确定我是否遗漏了一些重要的部分..

父.js

const Parent = () => {
 const postLike= usePostLike()
 const listData = useRecoilValue(getCardList)
 // listData looks like this -> 
 //[{ id:1, name: "Rose", avararImg: "url", image: "url", bodyText: "text", liked: false, likedNum: 1, ...etc }, 
 // { id:2, name: "Helena", avararImg: "url", image: "url", bodyText: "text", liked: false, likedNum: 1, ...etc },
 // { id: 3, name: "Gutsy", avararImg: "url", image: "url", bodyText: "text", liked: false, likedNum: 1, ...etc …
Run Code Online (Sandbox Code Playgroud)

performance reactjs react-hooks react-usememo recoiljs

5
推荐指数
1
解决办法
1万
查看次数

为什么这里使用 useMemo 而不是 useCallback ?

据我了解,两者之间的区别在于,如果返回函数、对象或数组,则使用 useCallback,而返回原语时则使用 useMemo。但我正在查找去抖(这是文章: https: //dmitripavlutin.com/react-throttle-debounce/,它说 useMemo 将是一个更好的解决方案。使用 useCallback

import { useState, useCallback } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
  const [query, setQuery] = useState("");
  let filteredNames = names;
  if (query !== "") {
    filteredNames = names.filter((name) => {
      return name.toLowerCase().includes(query.toLowerCase());
    });
  }
  const changeHandler = event => {
    setQuery(event.target.value);
  };
  const debouncedChangeHandler = useCallback(
    debounce(changeHandler, 300)
  , []);
  return (
    <div>
      <input 
        onChange={debouncedChangeHandler} 
        type="text" 
        placeholder="Type a query..."
      />
      {filteredNames.map(name => <div key={name}>{name}</div>)}
    </div> …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-hooks usecallback react-usememo

5
推荐指数
1
解决办法
6655
查看次数

哪个参数触发了 React.useMemo 重新计算?

这是我的 React hooks 代码:

function calc_c({a,b}){
  //some long calculation that is based on a,b
}
function MyComponent(params){
  var a=calc_a(params)
  var a=calc_b(params)
  var c=React.useMemo(()=>calc_c({a,b},[a,b])
}
Run Code Online (Sandbox Code Playgroud)

我的问题:如何找出哪些参数发生了[a,b]变化并导致了调用calc_c

编辑:我最终使用了 skyboyer 优秀答案的通用版本:

export function useChanged(name,value){
  function print_it(){
    console.log('changed',name)
  }
  React.useMemo(print_it,[value])
}
Run Code Online (Sandbox Code Playgroud)

reactjs react-hooks react-usememo

4
推荐指数
1
解决办法
1927
查看次数

如何在 React 中记住组件列表的一部分

寻找一些 React 渲染/useMemo 指南。

我有一个包含 2,000 多个项目的列表,每个项目都是一个 React 组件。有一个“当前选定”项目的突出显示,该项目独立于列表呈现。这允许我只渲染列表一次。

useMemo(_ => {
  <Item .../>
  <Item .../>
  ...
  <Item .../>
}, [contents])
Run Code Online (Sandbox Code Playgroud)

现在我添加了“展开”其中的列表项的功能,这只会添加新的 DOM 元素,而不会修改处于非展开状态的列表项。

您可以将每个部分想象Item为两部分:

function Item(props) {
  return
    <div>
      <SubItem />
      {
        if (props.open) {
          <OtherItem />
        } else {
          null
        }
      }
    </div>
}
Run Code Online (Sandbox Code Playgroud)
useMemo(_ => {
  <Item open={1 == current} .../>
  <Item open={2 == current} .../>
  ...
  <Item open={n == current} .../>
}, [contents, current])
Run Code Online (Sandbox Code Playgroud)

问题:有没有一种方法可以支持这一点,而不必在每次展开/折叠新项目时重新渲染整个列表?

不幸的是,扩展的 DOM 元素是“流动的”,因此扩展会将列表项推到它后面(不仅仅是悬停/覆盖)。

render reactjs react-hooks react-usememo

3
推荐指数
1
解决办法
4190
查看次数

我应该在 React 应用程序中删除所有不必要的 usecallback 和 memo 用法吗?

我正在开发一个相对较大的 React 代码库,并且我看到以前的开发人员使用memousecallback自由地认为通过使用这些代码可以提高性能。显然不是,这是一个例子

export default function QuestionHelper({ text }: { text: string }) {
  const [show, setShow] = useState<boolean>(false);

  const open = useCallback(() => setShow(true), [setShow]);
  const close = useCallback(() => setShow(false), [setShow]);

  return (
    <span style={{ marginLeft: 4 }}>
      <Tooltip show={show} text={text}>
        <QuestionWrapper
          onClick={open}
          onMouseEnter={open}
          onMouseLeave={close}
        >
          <Question size={16} />
        </QuestionWrapper>
      </Tooltip>
    </span>
  );
}
Run Code Online (Sandbox Code Playgroud)

该应用程序现在可以运行。但我拒绝修复它,因为该应用程序按预期工作。我怎样才能证明我们应该删除代码中所有不必要的memo和?usecallback

是否有客观的方法来说明删除这些内容的好处?

memo reactjs usecallback react-usememo react-usecallback

3
推荐指数
1
解决办法
722
查看次数

React 是否正在从 React.memo 转向 useMemo?

无论React.memouseMemo钩通过减少重新计算和重新描绘允许性能优化。然而,它们确实有效,因为 React.memo 用于包装函数组件,并且useMemo钩子几乎可以用于任何函数,甚至是纯计算。更重要的useMemo是,通常从父组件React.memo调用子组件,而通常在子组件本身的声明上调用。

虽然两者都有不同的优点,但一个优点React.memo是不必从每个父子关系中调用它。然而,随着钩子的发布,很明显 React 开发希望转向使用钩子来处理状态、副作用事件和其他效果的功能组件。虽然我认为 React 开发团队不会有勇气或无视他们的用户群React.memo在未来 2 年内随时删除,但我想知道他们是否希望最终用户出于风格原因停止使用 React.memo。就像他们有种被动积极地从类组件转移到带有钩子的功能组件。

当使用带有钩子的功能组件时,react 框架是否正在远离React.memo? 如果将来想跟上 React 最佳实践,习惯使用钩子版本会更好吗?

reactjs react-hooks react-memo react-usememo

2
推荐指数
1
解决办法
1784
查看次数

已记忆组件的子组件是否也已记忆?

从 useMemo 返回或包装在 React.memo() 中的子组件是否也被记忆?(抱歉,这可能是一个愚蠢的问题)

例如:

React.memo(<Parent><Child/></Parent>);
Run Code Online (Sandbox Code Playgroud)

这里Parent被记忆了,Child是否也被记忆了?

javascript memoization reactjs react-hooks react-usememo

2
推荐指数
1
解决办法
1270
查看次数

useRef、useMemo、useCallback 挂钩的生产用例是什么?

在外面柜台在很多的YouTube视频教程看到的例子,什么是实用/现实世界中使用案例useMemouseCallback

另外,我只看到了钩子的输入焦点示例useRef

请分享您为这些钩子找到的其他用例。

reactjs react-hooks usecallback use-ref react-usememo

2
推荐指数
1
解决办法
1628
查看次数

是否可以在组件内使用 useEffect 更新 useMemo 记忆值?

我正在尝试渲染必须通过的数据useMemo。我从 api 调用获取数据,因此我调用useEffect. 初始渲染工作返回一个空数组,但是一旦我调用 api,数据就不会更新。

import React from 'react'
import {fetchAccounts} from '../utils/api'

export default function Accounts() {
    const [accounts, setAccounts] = React.useState([])

React.useEffect(() => {
    setLoading(true)
    fetchAccounts().then((data) => {
        setAccounts(data)
    })
}, [])
const data = React.useMemo(() => accounts, [])

return <p>{JSON.stringify(data)}</p>}
Run Code Online (Sandbox Code Playgroud)

那么这可以在单个组件中工作吗?或者必须创建自定义挂钩?

reactjs use-effect react-usememo

2
推荐指数
1
解决办法
8757
查看次数