React useCallback 在第一次更改时不更新状态 onChange
React useCallback not updating state onChange on the first change
我正在尝试创建一个搜索下拉列表,但我的搜索过滤器未使用 useCallback
正确更新。 searchFilter 回调不会在第一个 onChange
上更新值
const [inputValue, setInputValue] = useState('');
const [opts, setOpts] = useState(allOptions);
const searchFilter = useCallback(
(val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
}, [inputValue] // state not being updated on first onChange
);
<textArea
onChange={(e) => searchFilter(e.target.value)}
value={inputValue}
/>
<ul>
{opts.map((option) => (
<li key={option.key}>
{option.text}
</li>
))}
</ul>
我能够通过取消回调来修复此错误:
const searchFilter = (val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
} // this works on every onChange
我的 useCallback
实施有什么问题?
我什至尝试在逻辑中添加一个 ref
,但这没有用。我在 React 文档中阅读了他们更喜欢使用 refs 的许多输入更改:
const [inputValue, setInputValue] = useState('');
const [opts, setOpts] = useState(allOptions);
const inputEl = useRef(null);
useEffect(() => {
inputEl.current = inputValue; // Write it to the ref
});
const searchFilter = useCallback(
(val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
}, [inputEl]
);
<textArea
ref={inputEl}
onChange={(e) => searchFilter(e.target.value)}
value={inputValue}
/>
** 注意我尝试添加一个 JS 代码段,但似乎我还不能将反应挂钩添加到 Whosebug。需要处理 React 版本 16.8+。如果有什么办法,请告诉我。
React 可以将多个 setState() 调用批处理到单个更新中以提高性能。
因为 this.props 和 this.state 可能会异步更新,所以您不应该依赖它们的值来计算下一个状态。
例如,此代码可能无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要修复它,请使用接受函数而非对象的第二种形式的 setState()。该函数将接收先前的状态作为第一个参数,应用更新时的道具作为第二个参数:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
查看有关反应的页面:状态和生命周期State Updates May Be Asynchronous
它似乎对我有用,不更新的值是什么?输入的值还是显示的选项?
我正在尝试创建一个搜索下拉列表,但我的搜索过滤器未使用 useCallback
正确更新。 searchFilter 回调不会在第一个 onChange
const [inputValue, setInputValue] = useState('');
const [opts, setOpts] = useState(allOptions);
const searchFilter = useCallback(
(val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
}, [inputValue] // state not being updated on first onChange
);
<textArea
onChange={(e) => searchFilter(e.target.value)}
value={inputValue}
/>
<ul>
{opts.map((option) => (
<li key={option.key}>
{option.text}
</li>
))}
</ul>
我能够通过取消回调来修复此错误:
const searchFilter = (val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
} // this works on every onChange
我的 useCallback
实施有什么问题?
我什至尝试在逻辑中添加一个 ref
,但这没有用。我在 React 文档中阅读了他们更喜欢使用 refs 的许多输入更改:
const [inputValue, setInputValue] = useState('');
const [opts, setOpts] = useState(allOptions);
const inputEl = useRef(null);
useEffect(() => {
inputEl.current = inputValue; // Write it to the ref
});
const searchFilter = useCallback(
(val) => {
setInputValue(val);
const filter = val.toUpperCase();
const ops = options.filter((opt) => opt.text.toUpperCase().indexOf(filter) > -1);
setOpts(ops);
}, [inputEl]
);
<textArea
ref={inputEl}
onChange={(e) => searchFilter(e.target.value)}
value={inputValue}
/>
** 注意我尝试添加一个 JS 代码段,但似乎我还不能将反应挂钩添加到 Whosebug。需要处理 React 版本 16.8+。如果有什么办法,请告诉我。
React 可以将多个 setState() 调用批处理到单个更新中以提高性能。 因为 this.props 和 this.state 可能会异步更新,所以您不应该依赖它们的值来计算下一个状态。
例如,此代码可能无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要修复它,请使用接受函数而非对象的第二种形式的 setState()。该函数将接收先前的状态作为第一个参数,应用更新时的道具作为第二个参数:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
查看有关反应的页面:状态和生命周期State Updates May Be Asynchronous
它似乎对我有用,不更新的值是什么?输入的值还是显示的选项?