gpt4 book ai didi

javascript - React - setTimeout 触发错误组件的样式更改

转载 作者:行者123 更新时间:2023-12-01 01:56:04 26 4
gpt4 key购买 nike

转载于此:https://jsfiddle.net/69z2wepo/204131/

父组件有两个以不同“衰减”率呈现的“通知”。

class Page extends React.Component {
constructor(props) {
super(props);

this.state = {
notifications: [
{ message: "I am the first component", code: 1, decay: 2000 },
{ message: "I am the second component", code: 2, decay: 5000 }
]
}

this.dismissNotification = this.dismissNotification.bind(this)
}

dismissNotification(code) {
this.setState({ notifications: this.state.notifications.filter(
n => n.code != code
)})
}

render() {
return (
<div>
{
this.state.notifications.map( (n, idx) => {
return (
<Notification
key={idx}
code={n.code}
decay={n.decay}
dismiss={this.dismissNotification}
>
{n.message}
</Notification>
)
})
}
</div>
)
}
}

组件设置自己的超时,这将导致动画,然后发送消息让它们关闭。

class Notification extends React.Component {
constructor(props) {
super(props)
this.state = {
style: { opacity: 1 }
}
this.makeRedFunction = this.makeRedFunction.bind(this)
}

componentDidMount = () => {
let timeout = parseInt(this.props.decay) || 2000

setTimeout(() => {
this.makeRedFunction();
setTimeout(() => {
this.dismiss();
}, 125)
}, timeout)
}

fadeOutFunction = () => {
let opacity = Math.floor(this.state.style.opacity * 10)
if (opacity > 0) {
opacity -= 1
setTimeout( () => { this.fadeOutFunction() }, 10)
}
let newState = Object.assign({}, this.state.style)
newState.opacity = opacity / 10
this.setState({ style: newState })
}

makeRedFunction = () => {
this.setState({ style: {color: 'red'} })
}

dismiss = () => {
this.props.dismiss(this.props.code)
}

render () {
return(
<div style={this.state.style}>{this.props.children}</div>
)
}
}

ReactDOM.render(
<Page/>,
document.getElementById('container')
);

不幸的是,当仅为其中一个通知调用了关闭函数时,两个通知的样式似乎都会发生变化。

一般来说,使用这种方法的组件的安装生命周期会出现奇怪的行为。

最佳答案

tl;dr: 如果列表中的元素具有状态,请勿使用数组索引作为键。使用每个数据点唯一的东西,并且不依赖于它在数组中的位置。在你的情况下,这将是 key={n.code} .

<小时/>

这与 React 如何协调组件树有关,并且是一个很好的例子来说明为什么使用数组索引为 key s 并不总是产生预期的结果。

当您改变元素列表时,key帮助 React 确定应该重用哪些节点。在你的情况下是从

<Notification />
<Notification />

<Notification />

但是 React 如何知道是删除第一个还是第二个 <Notification />节点?它通过使用key来做到这一点s。假设我们有

<Notification key="a">Foo</Notification>
<Notification key="b">Bar</Notification>

现在,如果它得到其中之一

<Notification key="a">...</Notification>

<Notification key="b">...</Notification>

在下一个渲染周期中,它知道删除 <Notification />key "b" (或"a")。

但是,您的问题是您基于 key数据在数组中的位置。所以在第一个渲染中你通过了

<Notification key="0">First</Notification>
<Notification key="1">Second</Notification>

然后,您将从列表中删除第一个通知,这会更改数组中第二个通知的位置,因此 React 会得到

<Notification key="0">Second</Notification>

这意味着

remove the element with key 1 and update the element with key 0 to show "Second"

但是带有 key="0" 的元素其样式已更改为红色文本,因此您会看到第二个通知中的文本为红色。

<小时/>

看看at the documentation了解更多信息。

关于javascript - React - setTimeout 触发错误组件的样式更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51034433/

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