[英]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.