Reactjs setState 异步
Reactjs setState asynchronous
我正在构建一个小搜索引擎并遇到以下问题:
每次我输入查询时,最后一个字母都不见了。我发现,它与 setState 有关并且它不是 asynchronous... 但我想不出解决方案我的情况。
她是我的职能:
searchHandler = ({ target: { value } }) => {
this.setState({ term: value });
this.updateMessage(value);
if(this.state.message.length === 0){
this.setState({hasMoreItems: false})
this.componentDidMount();
}else{
var requestUrl = 'https://questdb.herokuapp.com/all?q='
fetch(requestUrl + this.state.message).then((response)=>{
return response.json();
}) .then((data)=>{
this.setState({ tracks: data});
})
}
}
updateMessage = message => this.setState({ message });
你对我有什么建议吗?
非常感谢!
this.setState()
可以传递一个回调函数,该函数将在状态实际设置为新值后执行。你可以这样使用它:
this.setState({something: newValue}, () => {
console.log(this.state.something) // this will print out the new value
});
一般来说,您希望使用 setState()
的第二个参数,它接受一个回调函数,该函数将 运行 更新状态。这是一个例子:
import React, { Component } from 'react';
import { render } from 'react-dom';
class App extends React.Component {
state = {
value: '',
}
handleChange = (e) => {
e.preventDefault();
const { value } = e.target;
this.setState({ value }, () => {
console.log('Value is:', this.state.value );
})
}
render() {
return (
<input value={this.state.value} onChange={this.handleChange} />
)
}
}
render(<App />, document.getElementById('root'));
实例here.
有点晚了,但我不久前想出了一个解决方案,并且我在几乎所有需要它的项目中都在使用它。它不进行批处理,而是等待状态更新完成后再返回。哪个...有时正是您想要的。总之就是方便好用
setStateAsync 代码:
/**
* Allows you to await setState calls rather than use the callback function
* Declaration: private setStateAsync = setStateAsyncFactory(this);
* Usage: await this.setStateAsync({myProp: val});
* @param component
*/
export const setStateAsyncFactory = <P, S>(
component: React.Component<P, S>
) => {
return <K extends keyof S>(state:
((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
Pick<S, K> | S | null) => {
return new Promise(resolve => component.setState(state, () => resolve(undefined)));
};
};
/**
* Allows you to await setState calls rather than use the callback function
* Usage: await this.setStateAsync(component, {myProp: val});
* @param component
*
*/
export const setStateAsyncDirect = <P, S, K extends keyof S>(
component: React.Component<P, S>,
state:
((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
Pick<S, K> | S | null
) => new Promise(resolve => component.setState(state, () => resolve(undefined)));
用法:
export class FooEntry extends React.PureComponent<FooEntryProps, FooEntryState> {
private setStateAsync = setStateAsyncFactory(this);
...
private someAsyncFunc = async () => {
await this.setStateAsync({ foo: 3});
}
我正在构建一个小搜索引擎并遇到以下问题:
每次我输入查询时,最后一个字母都不见了。我发现,它与 setState 有关并且它不是 asynchronous... 但我想不出解决方案我的情况。
她是我的职能:
searchHandler = ({ target: { value } }) => {
this.setState({ term: value });
this.updateMessage(value);
if(this.state.message.length === 0){
this.setState({hasMoreItems: false})
this.componentDidMount();
}else{
var requestUrl = 'https://questdb.herokuapp.com/all?q='
fetch(requestUrl + this.state.message).then((response)=>{
return response.json();
}) .then((data)=>{
this.setState({ tracks: data});
})
}
}
updateMessage = message => this.setState({ message });
你对我有什么建议吗?
非常感谢!
this.setState()
可以传递一个回调函数,该函数将在状态实际设置为新值后执行。你可以这样使用它:
this.setState({something: newValue}, () => {
console.log(this.state.something) // this will print out the new value
});
一般来说,您希望使用 setState()
的第二个参数,它接受一个回调函数,该函数将 运行 更新状态。这是一个例子:
import React, { Component } from 'react';
import { render } from 'react-dom';
class App extends React.Component {
state = {
value: '',
}
handleChange = (e) => {
e.preventDefault();
const { value } = e.target;
this.setState({ value }, () => {
console.log('Value is:', this.state.value );
})
}
render() {
return (
<input value={this.state.value} onChange={this.handleChange} />
)
}
}
render(<App />, document.getElementById('root'));
实例here.
有点晚了,但我不久前想出了一个解决方案,并且我在几乎所有需要它的项目中都在使用它。它不进行批处理,而是等待状态更新完成后再返回。哪个...有时正是您想要的。总之就是方便好用
setStateAsync 代码:
/**
* Allows you to await setState calls rather than use the callback function
* Declaration: private setStateAsync = setStateAsyncFactory(this);
* Usage: await this.setStateAsync({myProp: val});
* @param component
*/
export const setStateAsyncFactory = <P, S>(
component: React.Component<P, S>
) => {
return <K extends keyof S>(state:
((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
Pick<S, K> | S | null) => {
return new Promise(resolve => component.setState(state, () => resolve(undefined)));
};
};
/**
* Allows you to await setState calls rather than use the callback function
* Usage: await this.setStateAsync(component, {myProp: val});
* @param component
*
*/
export const setStateAsyncDirect = <P, S, K extends keyof S>(
component: React.Component<P, S>,
state:
((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
Pick<S, K> | S | null
) => new Promise(resolve => component.setState(state, () => resolve(undefined)));
用法:
export class FooEntry extends React.PureComponent<FooEntryProps, FooEntryState> {
private setStateAsync = setStateAsyncFactory(this);
...
private someAsyncFunc = async () => {
await this.setStateAsync({ foo: 3});
}