在用useState填充之前清除数组

时间:2020-03-02 13:02:55

标签: reactjs react-hooks

如何清除数组并立即使用钩子(useState)进行反应填充

const [log, setLog] = useState([]);

const onSubmit = data => {
  let num = parseInt(data.num);
  setLog([]);
  for (let i = 1; i <= num; i++) {
    axios
      .get(data.url)
      .then(function(response) {
        setLog([...log, { type: "ok", message: "Good" }]);
      })
      .catch(function(error) {
        setLog([...log, { type: "error", message: "Bad" }]);
      });
  }
};

在此代码中,setLog([])无法清除数组,因为它是异步的。我该如何处理?预先感谢。

编辑:我正在创建一个到URL的请求日志并保存请求结果。可以是1次尝试或多次尝试,我必须记录所有响应。每次按下提交按钮时,都必须清除日志并重新启动请求。

3 个答案:

答案 0 :(得分:1)

不受欢迎的意见

使用类组件。它提供当前状态的访问器。

class SomeComponent extends Component {
  state = {
    isSubmitting: false,
    logs: []
  }

  async submit(data){
    const num = data.num;
    if (this.isSubmitting) {
      return;
    }

    let logs = [];
    this.setState({ logs, isSubmitting: true });

    for (const i = 0; i < num; i++) {
      await axios.get(data.url)
        .then(() => {
          logs = logs.concat({ type: "ok", message: "Good" });
          this.setState({ logs });
        })
        .catch(() => {
          logs = logs.concat({ type: "error", message: "Bad" })
          this.setState({ logs })
        })
    }

    this.setState({ isSubmitting: false });
  }

  render(){
    return (
      <form onSubmit={() => this.submit(getSomeData())}></form>
    )
  }
}


// use this if you want the request to be executed parallely

  async submit(data){
    const num = data.num;
    if (this.isSubmitting) {
      return;
    }

    let logs = [];
    this.setState({ logs, isSubmitting: true });

    const requests = []
    for (const i = 0; i < num; i++) {
      requests.push(
        axios.get(data.url)
          .then(() => {
            logs = logs.concat({ type: "ok", message: "Good" });
            this.setState({ logs });
          })
          .catch(() => {
            logs = logs.concat({ type: "error", message: "Bad" })
            this.setState({ logs })
          })
      )
    }

    await Promise.all(requests)

    this.setState({ isSubmitting: false });
  }

答案 1 :(得分:0)

为什么要先做setLog([])然后再做setLog([...log, ]);

如果您想setLog不包含以前的log内容,请执行以下操作:

const [log, setLog] = useState([]);

const onSubmit = data => {
  let num = parseInt(data.num);
  for (let i = 1; i <= num; i++) {
    axios
      .get(data.url)
      .then(function(response) {
        setLog([{ type: "ok", message: "Good" }]);
      })
      .catch(function(error) {
        setLog([{ type: "error", message: "Bad" }]);
      });
  }
};

编辑:好的,我想我理解您的需求。我不确定,请尝试以下操作

const [log, setLog] = useState([]);

const onSubmit = data => {
  let num = parseInt(data.num);
  setLog([]);
  for (let i = 1; i <= num; i++) {
    axios
      .get(data.url)
      .then(function(response) {
        setState(prevLog => {
          prevLog.push({ type: "ok", message: "Good" });
          return {prevLog};
        });
      })
      .catch(function(error) {
        setState(prevLog => {
          prevLog.push({ type: "error", message: "Bad" });
          return {prevLog};
        });
      });
  }
};

答案 2 :(得分:0)

我认为这会起作用:

const [log, setLog] = useState([]);

const onSubmit = data => {
  let num = parseInt(data.num);

  for (let i = 1; i <= num; i++) {
    axios
      .get(data.url)
      .then(function(response) {
        setLog([{ type: "ok", message: "Good" }]);
      })
      .catch(function(error) {
        setLog([{ type: "error", message: "Bad" }]);
      });
  }
};