Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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 设置状态触发道具更改_Javascript_Reactjs - Fatal编程技术网

Javascript 设置状态触发道具更改

Javascript 设置状态触发道具更改,javascript,reactjs,Javascript,Reactjs,示例组件从定义组件接收数据(示例列表)。由于这些示例可以由用户编辑,因此它们被放置在状态窗体中,状态窗体还允许我们在每次状态更改时创建/删除其他字段 在输入的每次击键(handleChangeExample函数)时,状态都会改变,但属性(props.examples)似乎也会更新,我不明白为什么会这样 我认为示例组件属性应该在整个周期中保持不变/不变,除非我们显式保存块(saveBlock函数),这反过来会从父定义组件触发saveExamples函数 var Examples = React.c

示例组件从定义组件接收数据(示例列表)。由于这些示例可以由用户编辑,因此它们被放置在状态窗体中,状态窗体还允许我们在每次状态更改时创建/删除其他字段

在输入的每次击键(handleChangeExample函数)时,状态都会改变,但属性(props.examples)似乎也会更新,我不明白为什么会这样

我认为示例组件属性应该在整个周期中保持不变/不变,除非我们显式保存块(saveBlock函数),这反过来会从父定义组件触发saveExamples函数

var Examples = React.createClass({
    getInitialState: function() {
        return {
            examples: this.props.examples
        }
    },

    editBlock: function(event) {
//        this.setState({examples: this.props.examples});
        this.setState({editingBlock: !this.state.editingBlock});
    },

    saveBlock: function(event) {
        var that = this;
        var filtered_examples = [];

        this.state.examples.forEach(function(example) {
            if (example !== '') {
                filtered_examples.push(example);
            }
        });

        this.props.saveExamples(filtered_examples);
    },

    handleChangeExample: function(i) {
        var updated_examples = this.state.examples;
        updated_examples[i] = this.refs['example_' + i].getDOMNode().value.trim();

        this.setState({examples: updated_examples});
    },

    render: function() {
        var that = this;
        var fields = {};

        console.log(this.props.examples);
        console.log(this.state.examples);

        this.state.examples.forEach(function(example, i) {
            if (example !== '') {
                fields['example-' + i] =
                    <li className='editing__entry'>
                        <input type='text'
                               key={i}
                               ref={'example_' + i}
                               onChange={that.handleChangeExample.bind(null, i)}
                               defaultValue={example} />
                    </li>;
            }
        });

        fields['example-' + (this.state.examples.length+1)] =
            <li className='editing__entry'>
                <input type='text'
                       key={this.state.examples.length+1}
                       ref={'example_' + (this.state.examples.length+1)}
                       onChange={that.handleChangeExample.bind(null, (this.state.examples.length+1))}
                       defaultValue='' />
            </li>;

        return (
            <section className='definition__examples block'>
                    <div className='editing'>
                        <ul className='editing__fields'>
                            {fields}
                        </ul>
                    </div>
            <button onClick={this.saveBlock} className='button--primary--small'>Save changes</button>

            </section>
        );
    }
});


var Definition = React.createClass({
    getInitialState: function() {
        return {
            examples: this.props.definition.examples
        }
    },

    saveExamples: function(examples) {
        this.setState({examples: examples});
    },


    render: function() {
        var editingMode = this.props.editingMode;
        var object = this;

        return (
            <li className='definition'>
            <Examples editingMode={editingMode}
                      examples={this.state.examples}
                      saveExamples={this.saveExamples} />
            </li>
        );
    }
});

module.exports = Definition;
var Examples=React.createClass({
getInitialState:函数(){
返回{
示例:this.props.examples
}
},
editBlock:函数(事件){
//this.setState({examples:this.props.examples});
this.setState({editingBlock:!this.state.editingBlock});
},
存储块:函数(事件){
var=这个;
var过滤_示例=[];
this.state.examples.forEach(函数(示例){
如果(例如!=''){
过滤的示例。推送(示例);
}
});
this.props.saveExamples(过滤的示例);
},
HandleChange示例:函数(i){
var更新的_示例=this.state.examples;
更新的_examples[i]=this.refs['example_'+i].getDOMNode().value.trim();
this.setState({examples:updated_examples});
},
render:function(){
var=这个;
变量字段={};
log(this.props.examples);
log(this.state.examples);
this.state.examples.forEach(函数(示例,i){
如果(例如!=''){
字段['example-'+i]=
  • ; } }); 字段['example-'+(this.state.examples.length+1)]=
  • ; 返回(
      {fields}
    保存更改 ); } }); 变量定义=React.createClass({ getInitialState:函数(){ 返回{ 示例:this.props.definition.examples } }, 保存示例:函数(示例){ this.setState({examples:examples}); }, render:function(){ var editingMode=this.props.editingMode; var object=这个; 返回(
  • ); } }); module.exports=定义;
    您看到这种行为是因为
    this.state.examples
    只是对
    this.props.examples
    的引用

    this.props.examples
    正在更新,原因与纯JavaScript中的预期行为相同:

    > var a = [ 'abc', 'def', 'ghi' ];
    undefined
    > a
    [ 'abc', 'def', 'ghi' ]
    > var b = a;
    undefined
    > b
    [ 'abc', 'def', 'ghi' ]
    > b[1] = 'DEF';
    'DEF'
    > b
    [ 'abc', 'DEF', 'ghi' ]
    > a
    [ 'abc', 'DEF', 'ghi' ]
    
    有两种方法可以解决这个问题。一种是创建
    this.props.examples
    的副本,并将其设置为
    this.state.examples
    (您可以通过Array.prototype.slice执行此操作):

    我认为这在您的情况下会起作用,因为
    示例
    只是一个字符串数组。但是,
    slice
    只会创建数组的浅层副本,因此如果元素是对象或数组,您仍然会更新
    this.props.examples

    另一个选项是用于更新您的状态。您可能还想看看

    下面是一个简化的示例,说明如何使用不变性帮助程序执行您正试图执行的操作:

    /**@jsx React.DOM*/
    var SomeComponent=React.createClass({
    getInitialState:函数(){
    返回{
    示例:this.props.examples,
    }
    },
    _handleChange:函数(索引,e){
    var updateObj={};
    updateObj[index]={$set:e.target.value};
    var newData=React.addons.update(this.state.examples,updateObj);
    this.setState({示例:newData});
    },
    render:function(){
    返回(
    

    道具: {JSON.stringify(this.props.examples,null,2)} 声明: {JSON.stringify(this.state.examples,null,2)} ); } } ); React.renderComponent(,document.getElementById('main'));
    getInitialState: function() {
        return {
            examples: this.props.examples.slice()
        }
    }
    
    /** @jsx React.DOM */
    
    var SomeComponent = React.createClass( {
    
      getInitialState : function() {
          return {
              examples : this.props.examples,
          }
      },
      _handleChange : function( index, e) {
          var updateObj = {};
          updateObj[ index ] =  { $set : e.target.value };
    
          var newData = React.addons.update( this.state.examples, updateObj );
    
          this.setState( { examples : newData } );
      },
    
      render : function() {
        return (
          <div>
            <input onChange={this._handleChange.bind(this, 0)}/><br/>
            <input onChange={this._handleChange.bind(this, 1)}/><br/>
            props:
            <pre>{JSON.stringify(this.props.examples,null,2)}</pre>
            state:
            <pre>{JSON.stringify(this.state.examples,null,2)}</pre>
          </div>
        );
      }
    } );
    
    React.renderComponent(<SomeComponent examples={ [ "ABC", "DEF" ] } />, document.getElementById( 'main' ) );