数组为什么会在 useEffect 外部反转自身?

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

Why does an array reverse itself outside of a useEffect?

问题

以下是翻译好的部分:

"recent" 是一个包含表单提交时输入值的数组。假设数组包含值 'London' 和 'Paris'。在 useEffect 内部,该数组应该返回 [London, Paris],但在 useEffect 外部,该数组将返回值 [Paris, London],即颠倒顺序。

一开始,我以为这是因为在 useEffect 内部,有一个名为 list 的第二个数组,它被赋予了 recent 数组的反转,但实际情况并非如此,因为即使在将反转后的数组赋给 list 后,recent 数组仍然按正确的顺序返回值。每当向 recent 添加新值时,recent 数组都会被重新赋值给 list,以便 list 始终是 recent 的反转。

如何修复这个问题?

const [recent, setRecent] = useState([]);
const [reverse, setReverse] = useState(true); // 用于确定是否反转列表
const [list, setList] = useState();

const RecentSearches = () => {
  useEffect(() => {
    if (reverse) {
      console.log(recent, "反转前"); // 返回 [London, Paris]
      setList(() => recent.reverse()); // 反转 recent
      setReverse(false); // 仅在函数运行时反转一次列表
      console.log(recent, "反转后"); // 返回 [London, Paris]
      console.log(recent[0], "第一个项"); // 返回 'London'
    }
  }, []);

  let searches;
  console.log("============");
  console.log(recent); // 返回 [Paris, London]
  console.log(recent[0], "第一个项"); // 返回 'Paris'
  console.log("---------");
  console.log(list); // 返回 [Paris, London]
  console.log("============");

  if (list) {
    searches = list.map((value, index) => (
      <button type="submit" form="form" key={index} onClick={() => setSearch(value)} onMouseEnter={() => setSearch(value)} onMouseLeave={() => setSearch("")}>
        {value}
        <i className="fa-solid fa-chevron-right"></i>
      </button>
    ));
  } else {
    searches = "";
  }
  return searches;
};

const [search, setSearch] = useState(""); // 输入框中的值

const handleSubmit = async event => {
  console.log("表单提交");
  event.preventDefault();
  setRecent([...recent, search]); // 将搜索值添加到 recent 数组的末尾
  setReverse(true); // 意味着 list 将设置为 recent 的反转版本,包括新值
  // ...
};

请注意,上述翻译中的代码部分没有被翻译,保持原样。

英文:

There is an array called recent that contains the values of an input when a form is submitted. Let's say the array contains the values 'London' and 'Paris'. Inside the useEffect, the array would return [London, Paris] as it should. However, outside the useEffect, the array would return the values [Paris, London] - the reverse.

At first, I thought that it was due to a second array list that was assigned the reverse of the recent array inside the useEffect, but this is not the case as the recent array still returns the values correct order after the reverse is assigned to list. The recent array is reassigned to list every time a new value is added to recent so that list is always the reverse of recent.

How do I fix this?

const [recent, setRecent] = useState([]);
const [reverse, setReverse] = useState(true); // says whether to reverse list or not
const [list, setList] = useState();
const RecentSearches = () =&gt; {
useEffect(() =&gt; {
if (reverse) {
console.log(recent, &quot;before reverse&quot;); // returns [&#39;London&#39;, &#39;Paris&#39;]
setList(() =&gt; recent.reverse()); // reverses recent
setReverse(false); // does not reverse list every time the function runs - only reverses it once
console.log(recent, &quot;after reverse&quot;); // returns [&#39;London&#39;, &#39;Paris&#39;]
console.log(recent[0], &quot;first item&quot;); // returns &#39;London&#39;
}
}, []);
let searches;
console.log(&quot;============&quot;);
console.log(recent); // returns [&#39;Paris&#39;, &#39;London&#39;]
console.log(recent[0], &quot;first item&quot;); // returns &#39;Paris&#39; 
console.log(&quot;---------&quot;);
console.log(list); // returns [&#39;Paris&#39;, &#39;London&#39;]
console.log(&quot;============&quot;);
if (list) {
searches = list.map((value, index) =&gt; ( &lt;
button type = &quot;submit&quot;
form = &quot;form&quot;
key = {
index
}
onClick = {
() =&gt; setSearch(value)
}
onMouseEnter = {
() =&gt; setSearch(value)
}
onMouseLeave = {
() =&gt; setSearch(&quot;&quot;)
} &gt; {
value
} &lt;
i className = &quot;fa-solid fa-chevron-right&quot; &gt; &lt; /i&gt; &lt; /
button &gt;
));
} else {
searches = &quot;&quot;;
}
return searches;
};
const [search, setSearch] = useState(&quot;&quot;); // value in the input
const handleSubmit = async event =&gt; {
console.log(&quot;form submitted&quot;);
event.preventDefault();
setRecent([...recent, search]); // adds search value to end of recent array
setReverse(true); // means that list will be set to reverse of recent with the new value
...
};

答案1

得分: 4

Array.reverse破坏性的,这意味着通过执行 recent.reverse(),实际上是在颠倒 recent。你应该使用以下方式:

setList([...recent].reverse())

这样你就不会直接改变 recent

英文:

Array.reverse is destructive which means that by doing recent.reverse() you're actually reversing recent. You should do instead

setList([...recent].reverse())

So you're not changing directly recent

huangapple
  • 本文由 发表于 2023年2月6日 02:34:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75354596.html
匿名

发表评论

匿名网友

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

确定