使用受控输入组件来反应useState Hook问题

时间:2020-04-20 22:41:22

标签: reactjs react-hooks react-state use-state

我的应用程序中有一个受控类组件,我想将其转换为利用钩子的功能组件。以前,通过在输入中设置event.target.value并将searchTerm的状态设置为该当前值,代码可以正常工作。但是,自从使用钩子进行重构以来,我注意到一个问题,searchTerm状态值是每个event.target.value前的字母。例如,如果我在输入栏中键入“ Joker”,则使用setSearchTerm(e.target.value)会得到searchTerm状态为“ Joke”而不是“ Joker”,直到我通过按下一个键导致另一个事件为止。我不确定为什么会这样,因为当我使用类组件执行此操作时,将this.state.searchTerm设置为e.target.value会达到预期的目标。如果我在输入字段中键入“ Joker”,则searchTerm状态实际上是“ Joker”。任何帮助,将不胜感激。谢谢!

import React, { useState, useRef } from 'react';
import './SearchBar.styles.scss';
import FontAwesome from 'react-fontawesome';
import {connect} from 'react-redux';
import {searchMovies} from '../../redux/redux-home/home.actions';

const SearchBar = ({ searchMovies }) => {
    const [searchTerm, setSearchTerm] = useState('');
    // constructor(){
    //     super();
    //     this.state={
    //         searchTerm: ''
    //     }
    // }

    const timeOut = useRef(null);

    const doSearch = e => {
        clearTimeout(timeOut.current);
        setSearchTerm(e.target.value);
        // this.setState({[e.target.name]: e.target.value});

        timeOut.current = setTimeout(() => {
            searchMovies(searchTerm);
        }, 500);
    }
    return(
        <div className="searchbar">
            <div className="searchbar-content">
                <FontAwesome className="fa-search" name="search" size="2x"/>
                <input type="text" placeholder="Movie" autoComplete="off" onChange={doSearch} value={searchTerm}/>
            </div>
        </div>
    );
}
const mapDispatchToProps = dispatch => ({
    searchMovies: search => dispatch(searchMovies(search))
});

export default connect(null, mapDispatchToProps)(SearchBar);
Console.log(e.target.value);之前和之后的

setSearchTerm都返回正确的值;但是,console.log(searchTerm);行之前和之后的setSearchTerm都返回不正确的值,该值是后面触发的一个事件。

2 个答案:

答案 0 :(得分:1)

您需要使用useEffect来监视searchTerm的变化:

useEffect(() => {
    // This will be called after searchTerm has been updated
    if (!searchTerm) return;
    clearTimeout(timeOut.current);
    timeOut.current = setTimeout(() => {
        searchMovies(searchTerm);
    }, 500);
}, [searchTerm]);

const doSearch = e => {
    // Just update the state, and let useEffect handle it
    setSearchTerm(e.target.value);
}

答案 1 :(得分:0)

key = unhexlify('3ED0920E5E6A0320D823D5987FEAFBB1')
msg = 'CEE9A53E3E463EF1F459635736738962&cmac='.encode()
mac, mact_calc = generate_cmac(key, msg)