反应覆盖对象中的状态变量

Posted

技术标签:

【中文标题】反应覆盖对象中的状态变量【英文标题】:React overwriting state variables in an object 【发布时间】:2017-03-25 00:23:14 【问题描述】:

当我尝试在我的状态下更新对象中的变量时,react 似乎覆盖了该对象中的其他变量。我写信给 book.title,然后是 book.author,但是当我记录 book 时,它只显示我写给它的最后一个值。

提前感谢您的帮助。

StepOne.js

class CreateListing extends Component 

    constructor(props) 
        super(props);
        this.handleTitleTextFieldChange = this.handleTitleTextFieldChange.bind(this);
        this.handleAuthorTextFieldChange = this.handleAuthorTextFieldChange.bind(this);
        this.handleYearTextFieldChange = this.handleYearTextFieldChange.bind(this);
        this.handlePriceTextFieldChange = this.handlePriceTextFieldChange.bind(this);
        this.handleDescTextFieldChange = this.handleDescTextFieldChange.bind(this);
        this.handleIsbnTextFieldChange = this.handleIsbnTextFieldChange.bind(this);
        this.log = this.log.bind(this);

        this.setState(
            book: 
                title: '',
                author: '',
                year: '',
                isbn: '',
                price: '',
                desc: ''
            
        )

    

    log() 
        console.log(this.state.book);
    

    handleTitleTextFieldChange(e) 
        this.setState(
            book: title: e.target.value
        );
    
    handleAuthorTextFieldChange(e) 
        this.setState(
            book: author: e.target.value
        );
    
    handleYearTextFieldChange(e) 
        this.setState(
            book: year: e.target.value
        );
    
    handleIsbnTextFieldChange(e) 
        this.setState(
            book: isbn: e.target.value
        );
    
    handlePriceTextFieldChange(e) 
        this.setState(
            book: price: e.target.value
        );
    
    handleDescTextFieldChange(e) 
        this.setState(
            book: desc: e.target.value
        );
    

    render() 
        return (
            <div>
                <h3 className="home-title">Create a listing</h3>
                <h4 className="create-subtitle">Step 1 - Fill in the book details</h4>

                <div className="create-title">
                    <div className="create-title-icon">
                        <i className="fa fa-book fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="What is the book title?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handleTitleTextFieldChange
                    />
                </div>


                <div className="create-author">
                    <div className="create-author-icon">
                        <i className="fa fa-user fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="Who are the book authors?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handleAuthorTextFieldChange
                    />
                </div>

                <div className="create-year">
                    <div className="create-year-icon">
                        <i className="fa fa-calendar fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="What year was the book published?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handleYearTextFieldChange
                    />
                </div>

                <div className="create-isbn">
                    <div className="create-isbn-icon">
                        <i className="fa fa-barcode fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="What is the book ISBN?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handleIsbnTextFieldChange
                    />
                </div>

                <div className="create-price">
                    <div className="create-price-icon">
                        <i className="fa fa-gbp fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="What is the desired price?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handlePriceTextFieldChange
                    />
                </div>

                <div className="create-desc">
                    <div className="create-desc-icon">
                        <i className="fa fa-bookmark fa-1.8x"></i>
                    </div>
                    <TextField
                        hintText="Short description about the condition?"
                        style=style.textField
                        multiLine=true
                        onChange=this.handleDescTextFieldChange
                    />
                </div>

                <div className="create-next-button">
                    <RaisedButton
                        label="Next"
                        backgroundColor=Colors.pink500
                        labelColor=Colors.white
                        fullWidth=true
                        onTouchTap=this.log
                        style=style.button/>
                </div>
            </div>
        );
    

【问题讨论】:

看看我的答案...这是正确的方法... 【参考方案1】:
 constructor(props) 
    super(props);
    ...
    resourceRemarks.forEach(x => 
        let resourceRemarkSwitch = "resourceRemarkSwitch" + x.index
        this.state = 
            ...this.state, [resourceRemarkSwitch]: true
        
    )

【讨论】:

【参考方案2】:
this.setState(
    book: ...this.state.book, title: e.target.value
)

【讨论】:

【参考方案3】:

您正在更改整个对象,而不仅仅是值。

this.setState(
    book: title: e.target.value
);

book 状态更改为您的对象,该对象仅包含一个标题。 此外,您的构造函数不应该调用 setState。应该是this.state = ...;

您可能想重新考虑您的组件是如何设置的,例如,如果这本书对象包含您的整个状态,您可以这样做:

class CreateListing extends Component 

constructor(props) 
    super(props);
    this.handleTitleTextFieldChange = this.handleTitleTextFieldChange.bind(this);
    this.handleAuthorTextFieldChange = this.handleAuthorTextFieldChange.bind(this);
    this.handleYearTextFieldChange = this.handleYearTextFieldChange.bind(this);
    this.handlePriceTextFieldChange = this.handlePriceTextFieldChange.bind(this);
    this.handleDescTextFieldChange = this.handleDescTextFieldChange.bind(this);
    this.handleIsbnTextFieldChange = this.handleIsbnTextFieldChange.bind(this);
    this.log = this.log.bind(this);

    this.State(
          title: '',
          author: '',
          year: '',
          isbn: '',
          price: '',
          desc: ''
    )



log() 
    console.log(this.state.book);


handleTitleTextFieldChange(e) 
    this.setState(
        title: e.target.value
    );

【讨论】:

【参考方案4】:

React's setState only does a shallow merge of the new and previous state,即嵌套对象被完全替换。

相反,请自己处理深度合并:

this.setState(
    book: Object.assign(, this.state.book, 
        title: e.target.value
    )
);

【讨论】:

以上是关于反应覆盖对象中的状态变量的主要内容,如果未能解决你的问题,请参考以下文章

更新反应状态而不覆盖先前的状态

OnSubmit 函数不会更新 React 中的反应钩子状态变量

反应:当我用后增量更改变量的状态时,程序中的值不同

第十二节:Hibernate 事务隔离,对象状态

Hibernate对象的三种状态

反应状态更新不正确