我的应用程序中有一个受控类组件,我想变成一个利用钩子的功能组件。以前,通过在输入中设置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);
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);
您可以复制e.target.value
并在以后的setTimeout
回叫中使用:
const doSearch = e => {
clearTimeout(timeOut.current);
setSearchTerm(e.target.value);
// Deep copy
const value = e.target.value.slice();
timeOut.current = setTimeout(() => {
searchMovies(value);
}, 500);
}