簡體   English   中英

使用受控輸入組件反應 useState Hook 問題

[英]React useState Hook issue with controlled input component

我的應用程序中有一個受控的 class 組件,我想將它變成一個使用鈎子的功能組件。 之前,通過在輸入中設置event.target.value並將 searchTerm 的searchTerm設置為當前值,代碼可以正常工作。 但是,由於使用鈎子進行重構,我注意到searchTerm state 值是每個event.target.value之前的字母的問題。 例如,如果我在輸入欄中鍵入“Joker”,使用setSearchTerm(e.target.value)我會得到 searchTerm state 是“Joke”而不是“Joker”,直到我通過按鍵引發另一個事件。 我不確定為什么會發生這種情況,因為當我使用 class 組件執行此操作時,將this.state.searchTerm設置為e.target.value將實現預期目標。 之前,如果我在輸入字段中輸入“Joker”,則searchTerm state 實際上是“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行之前和之后都返回錯誤的值,即后面的一個事件觸發器。

您需要使用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);
}
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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM