【问题标题】:Array being filled in inverse in React在 React 中逆向填充数组
【发布时间】:2021-11-24 08:34:11
【问题描述】:

我正在尝试用几个对象数组填充一个数组,但在第一次渲染时,这些值在数组内被反向填充,刷新后它们又回到应有的状态。


  const getProducts = async (data) => {
    await productServices
      .getProductsByTakeoffWizardStep(data)
      .then((response) => {
        setRows((rows) => [...rows, response.data]);
      })
      .catch((error) => {
        console.log(error.response);
      });
  };

  const getTakeoffIDs = () => {
    var i = 1;
    takeoffServices
      .getTakeoffSteps(5)
      .then((response) => {

        response.data.forEach((element) => {
          setSteps((steps) => [...steps, element.description]);
          setStepsID((stepsID) => [...stepsID, element.stepID]);
          var data = { StepID: element.stepID, TakeoffID: 4 };
          getProducts(data);
          setStepSequence((stepSequence) => [
            ...stepSequence,
            "Step " + i + "",
          ]);
          i = i + 1;
        });
      })
      .catch((error) => {
        console.log(error.response);
      });
  };

  useEffect(() => {
    setSteps([]);
    setStepsID([]);
    setRows([]);
    getTakeoffIDs();
  }, []);

所以在第一次渲染时,数组看起来像这样

(2) [Array(1), Array(2)]
0: Array(1)
0: {product: {…}, quantity: null}
length: 1
[[Prototype]]: Array(0)
1: Array(2)
0: {product: {…}, quantity: null}
1: {product: {…}, quantity: null}
length: 2
[[Prototype]]: Array(0)
length: 2
[[Prototype]]: Array(0)

刷新页面后是这样的

(2) [Array(2), Array(1)]
0: Array(2)
0: {product: {…}, quantity: null}
1: {product: {…}, quantity: null}
length: 2
[[Prototype]]: Array(0)
1: Array(1)
0: {product: {…}, quantity: null}
length: 1
[[Prototype]]: Array(0)
length: 2
[[Prototype]]: Array(0)

这可能是什么原因造成的,我能做些什么来解决它?

我正在使用 history.push() 从另一个页面访问该页面,但我传递的所有状态都不会影响获取过程,只会显示与我正在获取的数据无关的某些段落。

【问题讨论】:

  • 你能提供更多细节吗?或上下文。
  • @LHDi 我正在尝试使用 history.push() 从表中访问页面,根据表中的行,我正在获取数据。但是,当我进入页面时,我以相反的顺序接收数据,因此应该在第 1 页上的数据显示在第 2 页上,反之亦然。当我在保存值的状态“行”上使用 console.log 时,我意识到数组中的值是以相反的顺序插入的。 getProducts 函数中的 response.data 是我填写的初始数组,它依赖于从 getTakeoffIDs 获取的值。
  • ajax 请求,像大多数异步任务一样,可以以任何随机顺序解析。
  • @Thomas 我在几页中使用了这种方法,它对所有这些都非常有效。这个页面的唯一区别是我调用了一个从数据库中多次获取(getProducts)的函数。
  • 是的,您向服务器发送多个请求,它们可以以任意顺序返回。由于特定连接的延迟、某些 GC、某些锁定机制或一百万个其他原因。后续请求不会等待前一个请求完成后再响应。

标签: javascript arrays reactjs use-state


【解决方案1】:

我会这样写:

const getProduct = async (data) => {
  try {
    const response = await productServices.getProductsByTakeoffWizardStep(data);
    return response.data;
  } catch (error) {
    console.log(error.response);
  }
}

const getTakeoffIDs = () => {
  takeoffServices
    .getTakeoffSteps(5)
    .then(async (response) => {

      // try moving setSteps(), setStepsID() and setStepSequence() up here, so they don't wait for the products.

      const products = await Promise.all(
        response.data.map(element => getProduct({
          StepID: element.stepID,
          TakeoffID: 4
        }))
      );

      setRows((rows) => [
        ...rows,
        ...products
      ]);
      setSteps((steps) => [
        ...steps,
        ...response.data.map(element => element.description)
      ]);
      setStepsID((stepsID) => [
        ...stepsID,
        ...response.data.map(element => element.stepID)
      ]);
      setStepSequence((stepSequence) => [
        ...stepSequence,
        ...response.data((_, i) => `Step ${i + 1}`)
      ]);
    })
    .catch((error) => {
      console.log(error.response);
    });
};


useEffect(() => {
  setSteps([]);
  setStepsID([]);
  setRows([]);
  getTakeoffIDs();
}, []);
  • 我不会多次调用所有这些setState()s,而是将数据一次性添加到Array.map()
  • await 代表 所有 getProduct() 调用完成并立即推送它们;按顺序排列。

我不确定的一件事是您是否希望将 setRows() 与另一个 setter 一起调用,或者是否应该先调用其他 setter(因为数据可用)和 setRows() 应该是稍后在数据可用时调用。

【讨论】:

  • 行内数组的数量通常取决于 getTakeoffSteps 函数内部从数据库接收到的值的数量。因此,行内的数组数量与其他州相同,但它们不一定相互依赖。我试过你的答案,它奏效了。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 2015-10-11
  • 2013-12-13
相关资源
最近更新 更多