我正在尝试第一次使用React memo(),以防止不必要地重新呈现 TextInputs 用于 notes 。成功阻止了这些重新渲染,并且页面性能略有提高(实际示例中可能有数百个注释)。
但是,按下重置按钮后,会发生奇怪的事情。更改以前未编辑过的注释会导致旧注释重新出现在其他 TextInputs 中。
我的问题是: 为什么旧笔记会以这种方式重新出现?在保持最佳渲染效果的同时如何解决呢?
import React, { useState } from 'react';
export const ReRendering = () => {
const defaultNotes = [
{id: '0155', note: ''},
{id: '0197', note: ''},
{id: '0045', note: ''},
{id: '0244', note: ''},
{id: '0162', note: ''},
];
const [notes, setNotes] = useState(defaultNotes);
function updateNote(e) {
let newNotes = [];
notes.map(r => {
if(e.target.name === r.id) {
r.note = e.target.value;
}
newNotes.push(Object.assign(r));
});
setNotes(newNotes);
}
return (
<div className={'mt-5'}>
<h3>Notes</h3>
<table className={'table table-sm'}>
<thead>
<tr>
<th>ID</th>
<th>Note</th>
</tr>
</thead>
<tbody>
{notes.map(note => {
return (
<tr key={note.id}>
<td>
<input type={'text'}
disabled
className={'form-control border-0'}
value={note.id}
/>
</td>
<td>
<MemoTextInput
value={note.note}
name={note.id}
handleChange={updateNote}
/>
</td>
</tr>
)
})}
</tbody>
</table>
<button onClick={() => setNotes(defaultNotes)}>Revert</button>
</div>
)
};
const TextInput = ({value, handleChange, name}) => {
return (
<input
type={'text'}
className={'form-control'}
value={value}
onChange={handleChange}
name={name}
/>
)
};
function areEqual(prevProps, nextProps) {
return prevProps.value === nextProps.value;
}
const MemoTextInput = React.memo(TextInput, areEqual);
答案 0 :(得分:0)
分配partition by
时,您正在更改原始状态(默认音符),这可能会对其他所有内容产生不良影响。
r.note = e.target.value;
答案 1 :(得分:0)
问题与updateNote()函数有关。没有重新渲染的TextInputs上有一个旧版本的 updateNote(),因此也有一个旧版本的 notes 。
使用updateNotes()的修订版,它可以正常工作。
function updateNote({target}){
setNotes(oldNotes => {
const newNotes = [...oldNotes];
newNotes.filter(n => n.id === target.name)[0] = {...oldNotes.filter(n => n.id === target.name)[0]};
newNotes.filter(n => n.id === target.name)[0].note = target.value;
return newNotes;
})
}