【问题标题】:React useCallback not updating state onChange on the first changeReact useCallback 在第一次更改时不更新状态 onChange
【发布时间】:2020-04-07 16:03:13
【问题描述】:

我正在尝试创建一个搜索下拉列表,但我的搜索过滤器没有使用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

我对@9​​87654325@ 的实现有什么问题?

我什至尝试将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 sn-p 但似乎我还不能将反应钩子添加到 stackoverflow。需要处理 React 16.8+ 版本。如果有办法,请告诉我。

【问题讨论】:

    标签: reactjs react-hooks onchange usecallback


    【解决方案1】:

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

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

    【讨论】:

    • 啊,我添加了 inputValue 作为依赖项而不是 opts!它似乎工作正常
    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2021-04-21
      • 2020-05-08
      • 2016-03-20
      • 2021-02-02
      相关资源
      最近更新 更多