@dmitry-toster

Как правильно использовать useCallback в React?

я пытаюсь оптимизировать инлайновые функции, т.е такую запись

export default function({data, doSomething}) {
	return (
		<>
			{data.map(el => {
				<div onClick={() => doSomething(el.id)}>	
			})}
		</>
	)	
}

переделываю в такую:
export default function({data, doSomething}) {
	const handleClick = useCallback(id => doSomething(id), []);

	return (
		<>
			{data.map(el => {
				<div onClick={() => handleClick(el.id)}>	
			})}
		</>
	)	
}

и получаю ошибку:
Uncaught Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

в массив зависимостей также пробовал передать data, результат тот же
  • Вопрос задан
  • 139 просмотров
Решения вопроса 1
@8XL
function Child ({data, sayHi}) {

  const handleClick = useCallback(el => {
    sayHi(el)
  }, [])

  return (
    <div className="App">
      {data.map(el=>
        <div
          onClick={()=>handleClick(el)}
        >
          {el}
        </div>
      )}
    </div>
  )
}

export default function App() {
  const data = [1,2,3,4]
  
  const sayHi = (el) => {
    console.log('Hi '+ el)
  } 

  return (
    <Child data={data} sayHi={sayHi} />
  )
}


Вы обманываете, тут нет ошибки в хуке.

По-факту же ошибку вызывает doSomething( ), в которой, скорее всего, вызывается setState( ), который вызывает рендер и так далее до бесконечности, что не позволяет отрендерить.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
TchernyavskD
@TchernyavskD
Formoshlep
Конкретно в твоем примере - useCallback не нужен. Перечитай это в документации.
Ты на каждый рендер вызываешь функцию `useCallback`и передаешь в неё свой хендлер. Когда ты так делаешь, жс вынужден создать функцию прежде чем передать её в useCallback
Мемоизация работает тут так, что если у тебя депсы не изменились, useCallback игнорит новый аргумент и возвращает тебе старый хендлер
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы