Reactjs 对受控输入组件的状态钩子问题作出反应

Reactjs 对受控输入组件的状态钩子问题作出反应,reactjs,react-hooks,react-state,use-state,Reactjs,React Hooks,React State,Use State,我的应用程序中有一个受控类组件,我想把它变成一个利用钩子的功能组件。以前,通过在输入中设置event.target.value,并将searchTerm的状态设置为当前值,代码工作正常。然而,自从使用钩子进行重构以来,我注意到了一个问题,searchTerm状态值是每个event.target.value之前的字母。例如,如果我在输入栏中键入“Joker”,使用setSearchTerm(e.target.value)我会将searchTerm状态设置为“Joke”,而不是“Joker”,直到我

我的应用程序中有一个受控类组件,我想把它变成一个利用钩子的功能组件。以前,通过在输入中设置
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);
import React,{useState,useRef}来自“React”;
导入“./SearchBar.styles.scss”;
从“react FontAwesome”导入FontAwesome;
从'react redux'导入{connect};
从“../../redux/redux home/home.actions”导入{searchMovies};
常量搜索栏=({searchMovies})=>{
常量[searchTerm,setSearchTerm]=useState(“”);
//构造函数(){
//超级();
//这个州={
//搜索词:“”
//     }
// }
const timeOut=useRef(null);
const doSearch=e=>{
clearTimeout(timeOut.current);
设置搜索项(如目标值);
//this.setState({[e.target.name]:e.target.value});
timeOut.current=setTimeout(()=>{
searchMovies(searchTerm);
}, 500);
}
返回(
);
}
const mapDispatchToProps=调度=>({
searchMovies:search=>dispatch(searchMovies(搜索))
});
导出默认连接(null,mapDispatchToProps)(搜索栏);
Console.log(如target.value)
setSearchTerm
行之前和之后都返回正确的值;但是,
console.log(searchTerm)
setSearchTerm
行之前和之后都返回错误的值,该值是一个事件触发器之后的值

函数应用程序(){
function App() {
  const [value, setValue] = useState('');

  const timeOut = useRef(null);

  const change = (e) => {
    clearTimeout(timeOut.current);
    setValue(e.currentTarget.value)
    timeOut.current = setTimeout(() => {
      //see the diffetrence here
       console.log('hello', value, e.currentTarget.value)
  }, 500);
    console.log(e.target.value)
  }
  return (
    <div className="App">
      <input onChange={change} value={value} />
    </div>
  );
}

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(() => {
         // -----------------------------------
         console.log(searchTerm, e.currentTarget.value)
            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);
const[value,setValue]=使用状态(“”); const timeOut=useRef(null); 常数变化=(e)=>{ clearTimeout(timeOut.current); 设置值(如currentTarget.value) timeOut.current=setTimeout(()=>{ //看到这里的差异了吗 console.log('hello',value,e.currentTarget.value) }, 500); console.log(例如target.value) } 返回( ); } 从“React”导入React,{useState,useRef}; 导入“./SearchBar.styles.scss”; 从“react FontAwesome”导入FontAwesome; 从'react redux'导入{connect}; 从“../../redux/redux home/home.actions”导入{searchMovies}; 常量搜索栏=({searchMovies})=>{ 常量[searchTerm,setSearchTerm]=useState(“”); //构造函数(){ //超级(); //这个州={ //搜索词:“” // } // } const timeOut=useRef(null); const doSearch=e=>{ clearTimeout(timeOut.current); 设置搜索项(如目标值); //this.setState({[e.target.name]:e.target.value}); timeOut.current=setTimeout(()=>{ // ----------------------------------- console.log(searchTerm,e.currentTarget.value) searchMovies(searchTerm); }, 500); } 返回( ); } const mapDispatchToProps=调度=>({ searchMovies:search=>dispatch(searchMovies(搜索)) }); 导出默认连接(null,mapDispatchToProps)(搜索栏);
您需要使用
useffect
来监视
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);
}

请尝试
searchMovies(e.target.value)
,它会给出一个错误,即未定义-无法读取nullconsole事件的属性“value”,并查看您得到了什么。如果我记录它,我会得到正确的值。输入字段中的小丑是e.target.value中的小丑。我不确定是什么导致了setSearchTerm(例如target.value);在我的代码中,我放置了两个console.log以查看setSearchTerm之前和之后的值。两个日志都返回值one event trigger behind。只有一件事,请不要忘记在装载后将调用一次useEffect,因此请确保searchTerm中有内容(我已更新了答案)