我尝试做的是动态添加新元素并在将来某个时候更改其样式。所以要做到这一点,我尝试创建一个进入状态的对象,并且将包含两个具有设置为它们的数组值的属性:一个是保存元素本身的数组,另一个是保存与之关联的样式的数组。
但由于某种原因,即使我尝试创建一个包含两个属性的对象的副本(有人说将状态视为在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关于如何获取对数组索引的引用,以便每当我更新状态时它都会获取它,但最终,它最终只是使该值最终并保持静态(我认为)
注意:代码是更大代码的超级简化版本,但我在这里的代码是造成问题的基本代码
答案 0 :(得分:0)
首先,我想在您的代码中指出我认为是拼写错误的内容。在componentDidMount()
中,您在推送到img
的{{1}}组件上设置了以下道具:
pagesCopy
由于当时style={this.state.pages.pageStyle[0]}
是一个空数组,我相信你的意思是按如下方式设置道具:
this.state.pages.pageStyle
一旦修复,我认为你已经正确地诊断了原因。也就是说,您存储在style={pagesCopy.pageStyle[0]}
中的img
组件包含对对象的引用(this.state.pages.pageElements[0]
,后来变为pagesCopy.pageStyle[0]
)。当您调用this.state.pages.pageStyle[0]
时,您正在创建一个新对象而不是改变旧对象。这是一个问题,因为changeStyles()
组件上的样式prop仍包含对旧对象的引用,该引用未更改。
如果你需要在紧张的情况下完成这项工作,我的建议是直接在img
方法的this.state.pages.pageStyle[0]
中改变对象,然后调用changeStyles()
。调用forceUpdate()
将导致重新渲染。 forceUpdate()
组件将重新渲染,其样式prop将包含对具有新属性值的旧对象的引用。以下代码可以解决这个问题:
img
现在,我要强调这是非常非常糟糕的做法。直接变异状态几乎总是一个坏主意。如果有充分的理由这样做,我还没有听说过。
以下是关于如何在不直接改变状态的情况下执行此操作的建议。
changeStyle: function() {
var styles = this.state.pages.pageStyle[0];
styles.position = 'absolute';
styles.transform = 'translate(50px,100px)';
this.forceUpdate();
}