反应useCallback不会在第一次更改时更新状态onChange

我正在尝试创建一个搜索下拉列表,但是我的搜索过滤器未正确使用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文档中阅读了他们喜欢使用ref的许多输入更改:

const [inputvalue,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代码段,但看来我还不能向stackoverflow添加react钩子。需要处理React版本16.8+。如果可以的话,请告诉我。

ykxsky 回答:反应useCallback不会在第一次更改时更新状态onChange

这似乎对我有用,它没有更新什么价值?输入值还是显示的选项?

https://codesandbox.io/s/brave-mcnulty-pysjj

,

React可以将多个setState()调用批处理为一个更新,以提高性能。 由于this.props和this.state可以异步更新,因此您不应依赖于它们的值来计算下一个状态。

例如,此代码可能无法更新计数器:

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,});

要修复此问题,请使用第二种形式的setState(),它接受一个函数而不是一个对象。该函数将接收先前的状态作为第一个参数,而将应用更新时的props作为第二个参数:

// Correct
this.setState((state,props) => ({
  counter: state.counter + props.increment
}));

检查有关反应的页面:状态和生命周期State Updates May Be Asynchronous

本文链接:https://www.f2er.com/2492412.html

大家都在问