去抖动异步/等待并更新组件状态

时间:2019-09-13 11:15:48

标签: reactjs async-await debounce

我对防抖异步功能有疑问。为什么我的回答不确定? validatePrice是ajax调用,我从服务器接收响应并将其返回(确定已定义)。

我想在用户停止写入并在收到响应后更新状态后拨打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;
        });
        };
    }

2 个答案:

答案 0 :(得分:1)

您可以使用throttle-debounce库来实现您的目标。

导入代码在顶部

import { debounce } from 'throttle-debounce';

constructor中定义以下代码

// Here I have consider 'doPriceValidationFunc' is the async function
this.doPriceValidation = debounce(400, this.doPriceValidationFunc);

就是这样。

答案 1 :(得分:1)

请在下面使用lodash debounce函数查找工作代码。

这也是enter image description here的玩法。

一些更改:-

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);

希望有帮助!