去抖 async/await 并更新组件状态
debounce async/await and update component state
我对 debounce 异步函数有疑问。为什么我的回应是不确定的? validatePrice 是 ajax 调用,我从服务器收到响应并且 return 它(它是肯定定义的)。
我想在用户停止写入后进行 ajax 调用,并在收到响应后更新状态。我这样做对吗?
handleTargetPriceDayChange = ({ target }) => {
const { value } = target;
this.setState(state => ({
selected: {
...state.selected,
Price: {
...state.selected.Price,
Day: parseInt(value)
}
}
}), () => this.doPriceValidation());
}
doPriceValidation = debounce(async () => {
const response = await this.props.validatePrice(this.state.selected);
console.log(response);
//this.setState({ selected: res.TOE });
}, 400);
actions.js
export function validatePrice(product) {
const actionUrl = new Localization().getURL(baseUrl, 'ValidateTargetPrice');
return function (dispatch) {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST });
dispatch(showLoader());
return axios.post(actionUrl, { argModel: product }, { headers })
.then((res) => {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_FULFILLED, payload: res.data });
console.log(res.data); // here response is OK (defined)
return res;
})
.catch((err) => {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_REJECTED, payload: err.message });
})
.then((res) => {
dispatch(hideLoader());
return res.data;
});
};
}
您可以使用 throttle-debounce
库来实现您的目标。
在顶部导入代码
import { debounce } from 'throttle-debounce';
在 constructor
中定义以下代码
// Here I have consider 'doPriceValidationFunc' is the async function
this.doPriceValidation = debounce(400, this.doPriceValidationFunc);
就是这样。
请在下面找到具有 lodash
debounce
功能的工作代码。
这里还有 codesandbox link 可以玩。
一些变化:-
1) 我在同一个组件中定义了 validatePrice
而不是从 prop.
中获取
2) 在componentDidMount
.
中定义了debounce函数
import React from "react";
import ReactDOM from "react-dom";
import _ from "lodash";
import "./styles.css";
class App extends React.Component {
state = {
selected: { Price: 10 }
};
componentDidMount() {
this.search = _.debounce(async () => {
const response = await this.validatePrice(this.state.selected);
console.log(response);
}, 2000);
}
handleTargetPriceDayChange = ({ target }) => {
const { value } = target;
console.log(value);
this.setState(
state => ({
selected: {
...state.selected,
Price: {
...state.selected.Price,
Day: parseInt(value)
}
}
}),
() => this.doPriceValidation()
);
};
doPriceValidation = () => {
this.search();
};
validatePrice = selected => {
return new Promise(resolve => resolve(`response sent ${selected}`));
};
render() {
return (
<div className="App">
<input type="text" onChange={this.handleTargetPriceDayChange} />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
希望对您有所帮助!!!
我对 debounce 异步函数有疑问。为什么我的回应是不确定的? validatePrice 是 ajax 调用,我从服务器收到响应并且 return 它(它是肯定定义的)。
我想在用户停止写入后进行 ajax 调用,并在收到响应后更新状态。我这样做对吗?
handleTargetPriceDayChange = ({ target }) => {
const { value } = target;
this.setState(state => ({
selected: {
...state.selected,
Price: {
...state.selected.Price,
Day: parseInt(value)
}
}
}), () => this.doPriceValidation());
}
doPriceValidation = debounce(async () => {
const response = await this.props.validatePrice(this.state.selected);
console.log(response);
//this.setState({ selected: res.TOE });
}, 400);
actions.js
export function validatePrice(product) {
const actionUrl = new Localization().getURL(baseUrl, 'ValidateTargetPrice');
return function (dispatch) {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST });
dispatch(showLoader());
return axios.post(actionUrl, { argModel: product }, { headers })
.then((res) => {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_FULFILLED, payload: res.data });
console.log(res.data); // here response is OK (defined)
return res;
})
.catch((err) => {
dispatch({ type: types.VALIDATE_TARGET_PRICE_REQUEST_REJECTED, payload: err.message });
})
.then((res) => {
dispatch(hideLoader());
return res.data;
});
};
}
您可以使用 throttle-debounce
库来实现您的目标。
在顶部导入代码
import { debounce } from 'throttle-debounce';
在 constructor
// Here I have consider 'doPriceValidationFunc' is the async function
this.doPriceValidation = debounce(400, this.doPriceValidationFunc);
就是这样。
请在下面找到具有 lodash
debounce
功能的工作代码。
这里还有 codesandbox link 可以玩。
一些变化:-
1) 我在同一个组件中定义了 validatePrice
而不是从 prop.
2) 在componentDidMount
.
import React from "react";
import ReactDOM from "react-dom";
import _ from "lodash";
import "./styles.css";
class App extends React.Component {
state = {
selected: { Price: 10 }
};
componentDidMount() {
this.search = _.debounce(async () => {
const response = await this.validatePrice(this.state.selected);
console.log(response);
}, 2000);
}
handleTargetPriceDayChange = ({ target }) => {
const { value } = target;
console.log(value);
this.setState(
state => ({
selected: {
...state.selected,
Price: {
...state.selected.Price,
Day: parseInt(value)
}
}
}),
() => this.doPriceValidation()
);
};
doPriceValidation = () => {
this.search();
};
validatePrice = selected => {
return new Promise(resolve => resolve(`response sent ${selected}`));
};
render() {
return (
<div className="App">
<input type="text" onChange={this.handleTargetPriceDayChange} />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
希望对您有所帮助!!!