Reactjs React useCallback挂钩未按预期工作

Reactjs React useCallback挂钩未按预期工作,reactjs,react-hooks,Reactjs,React Hooks,如果道具没有改变,但下面的代码没有按预期工作,我一直在努力避免重新呈现子组件(InputBox组件)。 我怎样才能修好它? 如何避免重新呈现InputBox组件,因为该组件的名称相同,但memoizedCallbacks未被memoized <InputBox name={"test"} handleCb={memoizedCallback} id="name" /> //孩子 var InputBoxSet=new Set(); c

如果道具没有改变,但下面的代码没有按预期工作,我一直在努力避免重新呈现子组件(InputBox组件)。 我怎样才能修好它? 如何避免重新呈现InputBox组件,因为该组件的名称相同,但memoizedCallbacks未被memoized

<InputBox name={"test"} handleCb={memoizedCallback} id="name" />


//孩子
var InputBoxSet=new Set();
const InputBox=React.memo(函数InputBox({name,handleCb}){
//不应在名称或handlerCB更改时重新呈现
log(“%c InputBox渲染”,“颜色:橙色;字体重量:粗体;”);
InputBoxSet.add(名称);
InputBoxSet.add(handleCb);
log(“%c InputBoxSet”,“颜色:橙色;字体重量:粗体;”,InputBoxSet);
返回;
});
//母公司
让mySet=new Set();//检查回调函数在每次重新呈现时是否为新函数
常量问候语=反应备忘录(功能问候语(道具){
log(“%c!”,“颜色:绿色;字体重量:粗体;”);
const[name,setName]=React.useState(“”);
常量handleChange=(事件)=>{
控制台日志(“handleChange”);
setName(event.target.value);
};
//尽管进行了memoize回调,但memoize回调函数仍然是
//每次都创建新的,因此会导致子对象的重新渲染
const memoizedCallback=React.useCallback(
(事件)=>{
日志(“%c事件”,“颜色:红色;字体重量:粗体;”);
handleChange(event);//除非事件被更改,否则不调用原始函数
},
[活动]
);
添加(memoizedCallback);
log(“%c mySet”,“颜色:绿色;字体重量:粗体;”,mySet);
返回(
姓名:

{/*如何避免重新呈现此*/} {name?你好{name}:“请键入您的姓名”} ); },是平等的); 函数areEqual(prevProps,nextProps){ 返回prevProps.name==nextrops.name; } 功能应用程序(道具){ log(“%c渲染应用程序”,“颜色:黄色;字体重量:粗体;”); const[count,setCount]=React.useState(0); 常量nameArr=[]; 返回( setCount((c)=>c+1)}>{count}

); } render(,document.getElementById(“根”));
InputBox
组件接收2个道具名称(基本类型)和handleCb(参考类型) 使用的等式比较是

function areEqual(prevProps, nextProps) {
  return prevProps === nextProps;
}
例如,prevProps将是一个对象-

prevProps  = {
  name: 'someName',
  handleCb: someFunc
}
nextProps  = {
  name: 'someOtherName',
  handleCb: someFunc
}
例如,nextProps将是一个对象-

prevProps  = {
  name: 'someName',
  handleCb: someFunc
}
nextProps  = {
  name: 'someOtherName',
  handleCb: someFunc
}
由于两者是不同的引用,它们永远不会相等,因为
{}==={}
这总是错误的。 因此,
areEqual
将始终返回false,组件将重新渲染

你需要的是-

function areEqual(prevProps, nextProps) {
  return prevProps.name === nextProps.name;
}

memo
在父组件中的状态更改但子组件不依赖于它时使用。在您的情况下,每次
问候语
(当您在输入字段中键入时)中的内部状态发生变化时,传递的
memoizedCallback
依赖项都会发生变化,因此每次键入时,
道具
输入框
都会发生变化。这就是它不起作用的原因。谢谢,但我知道原因。我对重新呈现的原因进行了评论,但如何修复它。我如何避免这种情况?只要您传递的是每次输入更改都会更改的
memorizedCallback
,您就无法实现这一点。还有,你为什么要避免它?在你的情况下,重新渲染没有那么重要/昂贵。我只是好奇。实际上我想了解useCallback是如何工作的。我发现它只是避免调用实际函数,但每次渲染时都会创建新的包装函数。如果我有一个子树,它将这个记忆回调作为道具,那么每次重新呈现这个子树可能会很昂贵,那么我该如何解决这个重新呈现问题。让
memo
useCallback
不重新呈现/调用子组件/函数的唯一方法是不更新传递给
memo/useCallback
的props/dependency数组。一旦您理解了这一点,实现它应该是很简单的。我知道我可以通过使用函数AreeEqual(prevProps,nextProps){return prevProps.name==nextProps.name;}进行修复但我想避免渲染,即使我只在问候中更新如何避免重新渲染,因为名称没有改变,但每次都会创建memoizedcallback