我有一些输入是从对象数组中渲染的。
当我输入一个输入时,我会在数组上映射,找到相应的对象并设置输入值。
问题:在一个输入中键入一些字符,更改输入,键入字符。重复此步骤,观察先前的输入已清除,有时某些输入中会出现一些随机字符。
是什么原因导致这种行为?
如果我从SearchBar中删除了React.memo(),问题就不会再出现了。
我需要做什么才能使其与React.memo()一起使用。
const shouldSkipComponentUpdate = (prevProps, props) =>
prevProps.value === props.value;
const SearchBar = React.memo((props) => {
const { label, width, hasSearch, handleSearchChange, value } = props;
return (
<div width={width} style = { { margin: "15px", display: "inline" } }>
{label}
{hasSearch && (
<SearchInput
onChange={handleSearchChange}
value={value}
label={label}
/>
)}
</div>
);
}, (prevProps, props) => shouldSkipComponentUpdate(prevProps, props));
function DevicesContainer() {
const [searchBoxes, setSearchBoxes] = React.useState(() => {
return [
{
id: 1,
label: '',
width: '5%',
hasSearch: false,
value: ''
},
{
id: 2,
label: 'ID',
width: '5%',
value: '',
hasSearch: false
},
{
id: 3,
width: '10%',
label: 'Name',
value: '',
hasSearch: true
},
{
id: 4,
width: '10%',
label: 'Owner',
value: '',
hasSearch: true
},
{
id: 5,
width: '7%',
label: 'Availability',
value: '',
hasSearch: false
},
{
id: 6,
width: '10%',
label: 'Location',
value: '',
hasSearch: true
},
{
id: 7,
width: '20%',
label: 'Environment',
value: '',
hasSearch: true
},
{
id: 8,
width: '10%',
label: 'Firmware',
value: '',
hasSearch: true
},
];
});
function handleSearchChange(event, label) {
const {
target: { value }
} = event;
const updated = searchBoxes.map(elem => {
if (elem.label === label) {
return { ...elem, value };
}
return elem;
});
setSearchBoxes(updated);
}
return (
<main>
<SearchBars
searchBars={searchBoxes}
handleSearchChange={handleSearchChange}
/>
</main>
);
}
function SearchBars(props) {
const { searchBars, handleSearchChange } = props;
return (
<div style={ { margin: '20px' } }>
{searchBars.map(elem => (
<SearchBar
key={elem.id}
label={elem.label}
width={elem.width}
hasSearch={elem.hasSearch}
value={elem.value}
handleSearchChange={handleSearchChange}
/>
))}
</div>
);
}
function SearchInput(props) {
const { onChange, value, label } = props;
return (
<input
type="search"
value={value}
placeholder="Search"
onChange={event => onChange(event, label)}
/>
);
}
ReactDOM.render(
<DevicesContainer />,
document.getElementById('root')
);
答案 0 :(得分:0)
您可以更改handleSearchChange()
功能。请参阅setState
行为上的docs。您可能还注意到,该函数异步运行。我只是将映射功能移到了setSearchBox
更新句柄中,以将数据应用于先前的状态。
function handleSearchChange(event, label) {
const {
target: { value }
} = event;
setSearchBoxes((prevSearchBoxes) => {
let s = [...prevSearchBoxes];
let updated = s.map(elem => {
if (elem.label === label) {
return { ...elem, value };
}
return elem;
});
return updated;
});
}
另外请参阅React Docs中的以下说明。
与在类组件中找到的setState方法不同,useState可以 不会自动合并更新对象。您可以复制此 通过将功能更新程序形式与对象传播相结合来实现行为 语法:
setState(prevState => {
// Object.assign would also work
return {...prevState, ...updatedValues};
});
另一个选项是useReducer,它更适合于管理状态 包含多个子值的对象。