useEffect 在深度嵌套的 JSON 更新时未触发。

huangapple go评论98阅读模式
英文:

useEffect not triggered when a deeply nested JSON is updated

问题

I understand your request to exclude code translation. Here is the translated text:

"大家好,我是一个初学者,已经卡在这个问题上好几个小时了。我正在处理嵌套的 JSON 数据,但每当我更新 JSON 树中深处的值时,useEffect 钩子无法识别它,我应该如何解决这个问题?

这是我的代码流程,首先我使用以下函数获取要更新的值的路径:

function findValuePath(data, targetValue, currentPath = "") {
  if (typeof data === "object" && data !== null) {
    for (let key in data) {
      const path = currentPath ? `${currentPath}.${key}` : key;
      if (data[key] === targetValue) return path;
      const result = findValuePath(data[key], targetValue, path);
      if (result) return result;
    }
  }
}

一旦我有了值的路径,我就会更新嵌套的 JSON 中的 orderSubstatus

function updateNestedJSON(json, path, value) {
  const keys = path.split(".");
  let current = json;

  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i];
    if (!current[key]) {
      current[key] = {};
    }
    current = current[key];
  }

  const lastKey = keys[keys.length - 1];
  current[lastKey] = value;

  return json;
}

上述两个函数如下使用:

function handlePathAndUpdateSelected() {
   var temp;
   
    checkedArr.forEach(function (item) {
      const data = findValuePath(fetchedData, item);

      const cleanup =
        data.substr(0, data.lastIndexOf(".") + 1) + "orderSubStatus";
      temp = updateNestedJSON(fetchedData, cleanup, 2);
    });
    setfetchedData(temp);

  }

我将值从 1 更改为 2(orderSubStatus)。数据得到更新,但当我使用状态设置它时,useEffect 不会触发变化。我应该如何解决这个问题?请点击“接受全部”并在 Snack 中检查控制台日志。Snack 链接"

英文:

Hi All I'm a beginner and stuck with this issue for a couple of hours ,So im working with deeply nested json and whenever i update a value deep inside the JSON tree ,the useEffect hook doesn't recognize it ,how do I go about doing it ??

Here is my code flow ,so the value to be updated i get the path of it using this function

  function findValuePath(data, targetValue, currentPath = &quot;&quot;) {
    if (typeof data === &quot;object&quot; &amp;&amp; data !== null) {
      for (let key in data) {
        const path = currentPath ? `${currentPath}.${key}` : key;
        if (data[key] === targetValue) return path;
        const result = findValuePath(data[key], targetValue, path);
        if (result) return result;
      }
    }
  }

once i have the value path i update the orderSubstatus in the nested json

  function updateNestedJSON(json, path, value) {
    const keys = path.split(&quot;.&quot;);
    let current = json;

    for (let i = 0; i &lt; keys.length - 1; i++) {
      const key = keys[i];
      if (!current[key]) {
        current[key] = {};
      }
      current = current[key];
    }

    const lastKey = keys[keys.length - 1];
    current[lastKey] = value;

    return json;
  }

The above two functions are used as below

  function handlePathAndUpdateSelected() {
   var temp;
   
    checkedArr.forEach(function (item) {
      const data = findValuePath(fetchedData, item);

      const cleanup =
        data.substr(0, data.lastIndexOf(&quot;.&quot;) + 1) + &quot;orderSubStatus&quot;;
      temp = updateNestedJSON(fetchedData, cleanup, 2);
    });
    setfetchedData(temp);

  }

i am changing the value from 1 to 2 (orderSubStatus)<br>The data gets updated ,but when i set it using state it doesn't trigger useEffect change ,how do i possibly go about doing this ?

Click accept all and check console logs in the snack
Snack here

答案1

得分: 3

useEffect会使用比较器来检查是否更新了任何状态。当你使用setfetchedData(temp),而tempfetchedData的浅拷贝时,JavaScript会认为它们是同一个项目,不会视为更改。因此,useEffect()不会触发。

为了解决这个问题,通常我们会使用扩展运算符...)。它会创建一个全新的副本,不引用编程逻辑中的同一项。

function handlePathAndUpdateSelected() {
   var temp;
   
    checkedArr.forEach(function (item) {
      const data = findValuePath(fetchedData, item);

      const cleanup = data.substr(0, data.lastIndexOf(".")) + "orderSubStatus";
      temp = updateNestedJSON(fetchedData, cleanup, 2);
    });

    // 更改这一行
    setfetchedData([...temp]);
  }

如果你需要进一步的帮助,请告诉我。

英文:

This is related to React-Native rules.

useEffect will use comparator to check whether any state is updated. When you use setfetchedData(temp), and temp is a shallow copy of fetchedData, java-script will think that they are the same item and does not treat as a change. So, useEffect() will not trigger.

To fix this issue, mostly we will use spread operator (...). It will create a brand new copy which is not referring the same item in programming logic.

function handlePathAndUpdateSelected() {
   var temp;
   
    checkedArr.forEach(function (item) {
      const data = findValuePath(fetchedData, item);

      const cleanup = data.substr(0, data.lastIndexOf(&quot;.&quot;) + 1) + &quot;orderSubStatus&quot;;
      temp = updateNestedJSON(fetchedData, cleanup, 2);
    });

    //Change this line
    setfetchedData([...temp]);
  }

huangapple
  • 本文由 发表于 2023年6月12日 23:32:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458172.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定