Bei dieser Frage geht es eher darum, mehr darüber zu erfahren, wie React mit Änderungen umgeht und auf sie reagiert, als um die Implementierung, daher lasse ich den Immutable-Props-Apprach ein wenig weiterentwickeln.
Ich versuche, das erste Element eines Arrays abzurufen und es aus dem ursprünglichen Array zu entfernen, das als Requisite an die Komponente übergeben wird:
const ChildComponent = ( arrayToChange: Array<any>[] ) => { const elementFromArray = arrayToChange.shift(); }
Aus der Definition der Methode „shift()“::
Die Methodeshift() entfernt das erste Element aus dem Array und gibt das entfernte Element zurück. Diese Methode ändert die Länge des Arrays.
Obwohl die Variable elementFromArray jetzt die Elemente im Array enthält, ist das Array vollständig, es ist in keiner Weise betroffen und enthält weiterhin alle Elemente.
Aber wie ist das möglich? React sollte Requisiten als Referenz übergeben, daher sollte das ursprüngliche Array betroffen sein. Ich würde es verstehen, wenn React einige Schutzmaßnahmen einführen würde und diese Änderungen nicht im übergeordneten Element widergespiegelt würden. Ich möchte jedoch, dass die Änderungen trotzdem im untergeordneten Element widergespiegelt werden. Ich kann nichts Nützliches finden, um dieses Verhalten zu erklären. Die meisten Ressourcen erwähnen nur unveränderliche Methoden für Requisiten und wie man eine Problemumgehung findet, nicht jedoch den Grund oder die Logik dahinter.
Obwohl die Variable elementFromArray jetzt die Elemente im Array enthält, ist das Array vollständig, es ist in keiner Weise betroffen und enthält weiterhin alle Elemente. Wenn ich jedoch die Push()-Methode verwende, werden die Änderungen widergespiegelt und arrayToChange enthält ein weiteres Element.
Meine Frage ist: Warum reagiert arrayToChange unterschiedlich auf diese Methoden? Wenn „shift()“ den Inhalt nicht ändert, hoffe ich, dass push() dies auch nicht ändert.
如果您将渲染过程视为广度优先算法,则可以解释代码片段中的行为。
JSX 将转换:
进入以下 JavaScript:
React.createElement(ChildShowArray, { array: letter })
创建一个不会立即调用ChildShowArray
组件的结构。它将创建某种中间结构/对象,仅在渲染器要求它运行时运行。放置在
{...}
(JSX 上下文)中的 JavaScript 直接作为参数传递,因此直接解析。这意味着Parent
中的所有{JSON.stringify(letters)}
在子组件中的任何代码运行之前运行。当构建父结构完成后,渲染器将访问每个中间结构/对象并要求其渲染。这是从上到下完成的,这就是为什么第一个
ChildShowArray
渲染仍然显示完整数组的原因。然后渲染ChildChangeArray
并删除第一个元素。第二个ChildShowArray
渲染反映了此更改,并且在没有第一个元素的情况下进行渲染。请注意,
shift()
确实会更改letters
的内容,但是当调用它时,Parent
的内容已经呈现并且不再变化。此更改确实会影响下一次渲染的Parent
(单击代码片段中的“重新渲染”按钮)。它还会影响其下方使用相同数组引用的其他子组件的渲染。我不完全确定这个问题是什么,但我在这里冒险猜测一下,所以请在这里发表评论,我会在投票之前进行更改。
我认为你应该在你的子组件中尝试这个:
然后使用“data”映射到 jsx 中的输出
然后在父组件中,对 arrayToChange 进行移位。您可以将 useEffect 视为一个“观察者”,当数组长度发生变化时它将触发。