gpt4 book ai didi

javascript - React 不更新数组内对象的属性

转载 作者:行者123 更新时间:2023-11-28 06:33:47 26 4
gpt4 key购买 nike

我想做的是动态添加新元素并在将来的某个时候更改它们的样式。为此,我尝试创建一个对象,该对象将进入状态并包含两个属性,这些属性设置了一个数组值:一个是保存元素本身的数组,另一个保存与之关联的样式。

但出于某种原因,即使我尝试创建包含两个属性的对象的副本(有人说将状态视为在 stackoverflow 上不可变)并更新它,然后将状态设置为新对象,它好像还没更新。

我还尝试了here中的解决方案,但它仍然给出同样的问题。

var React = require('react');
var ReactDOM = require('react-dom');
var update = require('react-addons-update');


var Book = React.createClass({
getInitialState() {
return {
pages: {
pageElements: [], pageStyle: []
}
};
},
changeStyle: function (e) {
this.setState(update(this.state.pages.pageStyle[0],
{name: {$set: {position: 'absolute', transform: 'translate(50px,100px)'} }}));
},
componentDidMount: function () {
let pagesCopy = {
pageElements: this.state.pages.pageElements, pageStyle: []
};
pagesCopy.pageStyle.push({styles: {position: 'absolute'}});
pagesCopy.pageElements.push(
<img
key={0}
onMouseDown={this.changeStyle}
style={this.state.pages.pageStyle[0]}
src={'/pages/0'}
height="800px"
width="600px"/>);
this.setState({pages: pagesCopy});
},
render: function () {
return (
<div>
<section style={{position: 'relative', height:800, width:1200, margin: 'auto'}}>
{this.state.pages.pageElements}
</section>
</div>
)
}
});

ReactDOM.render(<Book/>, document.getElementById("content"));

我认为问题出在以下几行:

style={this.state.pages.pageStyle[0]}

它直接引用对象。我认为它正在获取该值并将该值永久设置为样式,并且由于只能存在状态的副本,因此它无法看到包含这两个属性的新对象上的更新值。我也做了research关于如何获取对数组索引的引用,以便每次更新状态时它都会获取它,但最终,它最终只是使该值成为最终值并保持静态(我认为)。

注意:该代码是较大代码的 super 简化版本,但我这里的代码是导致问题的基本代码

最佳答案

首先,我想指出您的代码中我认为有一个拼写错误的地方。在 componentDidMount() 中,您在插入 pagesCopyimg 组件上设置以下属性:

style={this.state.pages.pageStyle[0]}

由于 this.state.pages.pageStyle 当时是一个空数组,我相信您的意思是按如下方式设置 prop:

style={pagesCopy.pageStyle[0]}

一旦解决了这个问题,我认为您已经正确诊断了直接原因。也就是说,您存储在 this.state.pages.pageElements[0] 中的 img 组件包含对对象的引用 (pagesCopy.pageStyle[0 ],稍后变为 this.state.pages.pageStyle[0])。当您调用 changeStyles() 时,您正在创建一个新对象,而不是改变旧对象。这是一个问题,因为 img 组件上的 styles 属性仍然包含对旧对象的引用,而该对象未更改。

如果您需要在紧要关头完成这项工作,我的建议是直接在 changeStyles()< 中修改 this.state.pages.pageStyle[0] 中的对象 方法,然后调用 forceUpdate()。调用forceUpdate()将导致重新渲染。 img 组件将重新渲染,其 style 属性将包含对具有新属性值的旧对象的引用。下面的代码就可以解决这个问题:

changeStyle: function() {
var styles = this.state.pages.pageStyle[0];
styles.position = 'absolute';
styles.transform = 'translate(50px,100px)';
this.forceUpdate();
}

现在,我要强调这是非常非常糟糕的做法。直接改变状态几乎总是一个坏主意。如果有充分的理由这样做,我还没有听说过。

下面是关于如何在不直接改变状态的情况下执行此操作的建议。

var Book = React.createClass({

getInitialState() {
return {
pageElements: [
{
tagName: 'img',
props: {
src: 'http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg',
height: '800px',
width: '600px',
style: {
position: 'absolute'
}
}
}
]
};
},

changeStyle: function(e) {
this.setState(function(previousState) {
var newState = _.extend({}, previousState);
newState.pageElements[0].props.style = {
position: 'absolute',
transform: 'translate(50px,100px)'
};
return newState;
});
},

render: function () {
return (
<div>
<section style={{ position: 'relative', height: 800, width: 1200, margin: 'auto' }}>
{
this.state.pageElements.map(function(pageElement, index) {
return React.createElement(pageElement.tagName,
_.extend(pageElement.props, {
key: index,
onMouseDown: this.changeStyle.bind(this)
})
);
}.bind(this))
}
</section>
</div>
);
}

});

React.render(<Book/>, document.getElementById('content'));

关于javascript - React 不更新数组内对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34468337/

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