gpt4 book ai didi

reactjs - 为什么 React 的 DOM 协调没有按预期工作?

转载 作者:行者123 更新时间:2023-12-03 13:37:48 25 4
gpt4 key购买 nike

我正在尝试使用 React 用过渡交换元素的两个子元素。

<div style={{position: 'relative'}}>
{this.state.items.map((item, index) => (
<div
key={item}
style={{position: 'absolute',
transform: `translateY(${index * 20}px)`,
transition: '1s linear transform'}}>
{item}
</div>
))}
</div>

state.items 是一个包含两个项目的数组。重新排序后,两个子 div 应转换到新位置。

现实中发生的情况是,当第二个元素按预期转换时,第一个元素立即跳转。

据我所知,React 认为它可以重用其中一个子元素,但不能重用另一个,尽管文档说如果我们使用 key 属性,它应该始终重用元素:https://facebook.github.io/react/docs/reconciliation.html (至少,我是这么理解的)。

我应该对代码进行哪些更改才能使其按预期工作?或者这是 React 中的一个错误?

实例:http://codepen.io/pavelp/pen/jAkoAG

最佳答案

警告:我在这个答案中做出了一些假设,尽管如此,它还是阐明了您(以及之前我的)的一些问题。另外,我的解决方案几乎肯定可以简化,但为了回答这个问题,它应该足够了。

<小时/>

这是一个很好的问题。我有点惊讶地打开开发工具并查看交换项目时实际发生的情况。

如果你看一下,你可以有点看看React在做什么。第二个元素根本不改变其 style 属性,只是交换内部文本节点,而第一个元素作为新元素放入 dom 中。

如果我不得不猜测,这是因为交换数组中的两个项目的工作方式,其中至少一个项目被复制到临时变量并放回数组中。

我认为,也许如果你进行随机翻译,两个元素都会获得新样式的 Prop 和动画,但这只会更清楚地表明这不是预期的行为。

寻找解决方案的过程:

作为一个实验,如果我们提前创建节点,并通过 React.cloneElement 在渲染中传递索引属性会怎样。当我们这样做时,如果 index === 0 则渲染一个 span ,否则渲染一个 div 。无需担心 key 。

http://codepen.io/alex-wilmer/pen/pbaXzQ?editors=1010

现在打开开发工具就可以准确地说明 React 的意图。 React 保留元素并仅更改相关部分,在本例中为innerText 节点和元素类型。由于样式完全按照 1:1 交换,因此不需要更新样式。

解决方案:

你可以提前生成你的 React 元素,将它们保存在一个数组中,因此没有键可以随意移动并弄清楚如何放回 DOM 中。然后使用不同的数组来跟踪预期的顺序。可能非常复杂,但它有效!

http://codepen.io/alex-wilmer/pen/kXZKoN?editors=1010

const Item = function (props) {
return (
<div
style={{position: 'absolute',
transform: `translateY(${props.index * 20}px)`,
transition: '0.5s linear transform'}}>
{props.children}
</div>
)
}

const App = React.createClass({
getInitialState () {
return {
items: [
{item: 'One', C: <Item>One</Item>},
{item: 'Two', C: <Item>Two</Item>}
],
order: ['One', 'Two']
};
},
swap () {
this.setState({
order: [this.state.order[1], this.state.order[0]]
});
},
render: function () {
return <div>
<button onClick={this.swap}>Swap</button>
<div style={{position: 'relative'}}>
{this.state.items.map(x =>
React.cloneElement(x.C, {
index: this.state.order.findIndex(z => z === x.item)
}))
}
</div>
</div>;
}
});

关于reactjs - 为什么 React 的 DOM 协调没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38470305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com