Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React不从数组中的对象更新属性_Javascript_Reactjs - Fatal编程技术网

Javascript React不从数组中的对象更新属性

Javascript React不从数组中的对象更新属性,javascript,reactjs,Javascript,Reactjs,我想做的是动态添加新元素,并在将来某个时候更改它们的样式。为此,我尝试创建一个对象,该对象将进入状态,并包含两个属性,这些属性设置了一个数组值:一个是保存元素本身的数组,另一个保存与该元素相关联的样式 但出于某种原因,即使我尝试创建一个包含这两个属性的对象副本(有人说要将状态视为在stackoverflow上是不可变的)并对其进行更新,然后将状态设置为新对象,它似乎仍然没有更新 我也尝试了来自的解决方案,但它仍然给出了相同的问题 var React = require('react'); var

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

但出于某种原因,即使我尝试创建一个包含这两个属性的对象副本(有人说要将状态视为在stackoverflow上是不可变的)并对其进行更新,然后将状态设置为新对象,它似乎仍然没有更新

我也尝试了来自的解决方案,但它仍然给出了相同的问题

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"));
它直接引用对象的位置。我认为它会将该值永久地设置为样式,并且由于只能有状态的副本,因此它无法在包含这两个属性的新对象上看到更新的值。我还讨论了如何获取对数组索引的引用,以便它在每次更新状态时都会获取它,但最终,它只是将该值设置为final并使其保持静态(我认为)


注意:该代码是一个更大代码的超级简化版本,但我这里的代码是导致问题的基本代码。首先,我想指出您的代码中有一些我认为是打字错误的地方。在
componentDidMount()
中,您在推入
pageScope
img
组件上设置以下道具:

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

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

style={pagesCopy.pageStyle[0]}

一旦解决了这个问题,我想你已经正确地诊断出了近因。也就是说,您存储在
this.state.pages.pageElements[0]
中的
img
组件包含对对象的引用(
pageScope.pageStyle[0]
,该对象后来成为
this.state.pages.pageStyle[0]
)。调用
changeStyles()
时,您正在创建一个新对象,而不是修改旧对象。这是一个问题,因为
img
组件上的样式道具仍然包含对旧对象的引用,而旧对象的引用没有改变

如果需要在紧急情况下执行此操作,我的建议是直接在
changeStyles()
方法中的
this.state.pages.pageStyle[0]
中修改对象,然后调用
forceUpdate()
。调用
forceUpdate()
将导致重新渲染。
img
组件将重新渲染,其样式道具将包含对具有新属性值的旧对象的引用。下面的代码可以实现此目的:

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'));
var Book=React.createClass({
getInitialState(){
返回{
页面元素:[
{
标记名:“img”,
道具:{
src:'http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg',
高度:“800px”,
宽度:“600px”,
风格:{
位置:'绝对'
}
}
}
]
};
},
更改样式:函数(e){
this.setState(函数(previousState){
var newState=..extend({},previousState);
newState.pageElements[0]。props.style={
位置:'绝对',
转换:“转换(50px,100px)”
};
返回新闻状态;
});
},
渲染:函数(){
返回(
{
this.state.pageElements.map(函数(pageElement,索引){
返回React.createElement(pageElement.tagName,
_.extend(pageElement.props{
关键词:索引,,
onMouseDown:this.changeStyle.bind(this)
})
);
}.绑定(本)
}
);
}
});
React.render(,document.getElementById('content'));

首先,我想指出您的代码中有一些我认为是打字错误的地方。在
componentDidMount()
中,您在推入
pageScope
img
组件上设置以下道具:

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

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

style={pagesCopy.pageStyle[0]}

一旦解决了这个问题,我想你已经正确地诊断出了近因。也就是说,您存储在
this.state.pages.pageElements[0]
中的
img
组件包含对对象的引用(
pageScope.pageStyle[0]
,该对象后来成为
this.state.pages.pageStyle[0]
)。调用
changeStyles()
时,您正在创建一个新对象,而不是修改旧对象。这是一个问题,因为
img
组件上的样式道具仍然包含对旧对象的引用,而旧对象的引用没有改变

如果需要在紧急情况下执行此操作,我的建议是直接在
changeStyles()
方法中的
this.state.pages.pageStyle[0]
中修改对象,然后调用
forceUpdate()
。调用
forceUpdate()
将导致重新渲染。
img
组件将重新渲染,其样式道具将包含对具有新属性值的旧对象的引用。下面的代码可以实现此目的:

changeStyle: function() {
  var styles = this.state.pages.pageStyle[0];
  styles.position = 'absolute';
  styles.transform = 'translate(50px,100px)';
  this.forceUpdate();
}
现在,我要强调,这是非常非常糟糕的做法。直接改变状态几乎总是个坏主意。如果有好的理由