我有一些从对象数组中呈现的输入。
当我输入一个输入时,我映射到数组上,找到相应的对象并设置输入值。
问题:在一个输入中键入一些字符,更改输入,键入字符。重复此操作,观察先前的输入被清除,有时在某些输入中出现一些随机字符。
是什么导致了这种行为?
如果我将React.memo()从SearchBar中删除,问题就不再出现。
要使它与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')
);发布于 2019-07-11 20:43:28
您可以更改handleSearchChange()函数。参见关于文档行为的setState。您可能还会注意到,此函数异步运行。我刚刚将映射函数移到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中的以下说明。
与类组件中的setState方法不同,useState不会自动合并update对象。您可以通过将函数更新器表单与对象扩展语法相结合来复制此行为:
setState(prevState => {
// Object.assign would also work
return {...prevState, ...updatedValues};
});另一个选项是useReducer,它更适合于管理包含多个子值的状态对象。
https://stackoverflow.com/questions/56987642
复制相似问题