Javascript 当对单个输入调用onChange时,所有React输入元素都会重新呈现,即使输入上有memo,onChange上有useCallback

Javascript 当对单个输入调用onChange时,所有React输入元素都会重新呈现,即使输入上有memo,onChange上有useCallback,javascript,reactjs,state,rendering,memoization,Javascript,Reactjs,State,Rendering,Memoization,const{useReducer}=React const InputWithLabelAbove=({ labelText, 身份证件 一旦改变, 图案 价值 }) => { 返回( {labelText} ) } const MemoInputWithLabelAbove=React.memo(InputWithLabelAbove) 常量组件=()=>{ //计算对象 常量计算器bj={ 税款:'', 水:'', 能源:, 互联网:“, 传输:'', 食物:, 教育:'', 儿童保育:,

const{useReducer}=React
const InputWithLabelAbove=({
labelText,
身份证件
一旦改变,
图案
价值
}) => {
返回(
{labelText}
)
}
const MemoInputWithLabelAbove=React.memo(InputWithLabelAbove)
常量组件=()=>{
//计算对象
常量计算器bj={
税款:'',
水:'',
能源:,
互联网:“,
传输:'',
食物:,
教育:'',
儿童保育:,
其他保险:'',
其他成本:''
}
//陈述
常量输入值={
总计:'',
showCalculator:错,
计算总数:0,
计算:{
…计算器
}
}
//形态状态还原
const[values,setValues]=useReducer(
(state,newState)=>({…state,…newState}),
输入值
)
//更改函数以处理字段状态。
const handleChange=React.useCallback((e,type)=>{
常量{value,id}=e.target
console.log('onchange')
常数re=/^[0-9\b]+$/
const const converted=!re.test(值)| | value.length==0?'':parseInt(值,10)
如果(类型=='calculator'){
常量对象={
…values.calc,
[id]:已转换
}
setValues({calc:{…obj}})
}
},[values.calc])
const Calclaberarr=[“议会税”、“水”、“能源(天然气和/或电力)”、“互联网”、“交通”、“食品”、“儿童教育”、“儿童保育”、“其他保险”、“其他基本成本”]
返回(
{Object.entries(values.calc).map((i,index)=>{
返回
handleChange(即“计算器”)}
值={i[1]}
/>
}
)}
)
}
ReactDOM.render(
,
document.getElementById('reactBind')
)

跳出的一件事是输入组件上的这个属性:

onChange={(e) => handleChange(e, 'calculator')}
即使
handleChange
已被记忆化,您每次都在创建一个新的箭头函数来调用记忆化的函数。因此,即使输入被记忆,每次都会看到一个新的
onChange

您需要传递一个稳定的函数以避免重新渲染,例如:

const onChange = React.useCallback(
    e => handleChange(e, "calculator"),
    [handleChange]
);
然后

onChange={onChange}

(我不清楚您在哪里定义了
handleChange
;如果它在呈现这些输入的组件中,您可能可以将该定义与上面的定义组合在一个
useCallback
中,或者如果是多个回调,则可能是
useMemo
。尽管小片段也很好。)

欢迎使用堆栈溢出!请用一个演示问题的例子更新您的问题(上述内容已接近尾声,但我们需要了解输入组件是如何记忆的等等),最好是使用堆栈片段(
[]
工具栏按钮)的可运行组件。堆栈代码段支持React,包括JSX。一个可运行的示例可以帮助您确保问题包含所有需要回答的信息,并帮助回答问题的人确保他们的答案完整。同样,请提供一个可运行的MRE。我已经完成了,很抱歉,我没有太多关于堆栈溢出的经验,所以我已经习惯了。请参阅上面的代码片段。(哎呀,在
useCallback
中遗漏了依赖项;如果看不到它,请点击refresh。)感谢您的回答,我已经尝试了一下,它似乎仍然会重新呈现所有输入。不确定为什么这仍然不起作用:/已更新以使用备注显示React typescript组件。