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

React overwriting state variables in an object

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

提前感谢您的帮助。

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>
        );
    }
}

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
    })
});

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

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

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

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

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
    });
}
this.setState({
    book: {...this.state.book, title: e.target.value}
})
 constructor(props) {
    super(props);
    ...
    resourceRemarks.forEach(x => {
        let resourceRemarkSwitch = "resourceRemarkSwitch" + x.index
        this.state = {
            ...this.state, [resourceRemarkSwitch]: true
        }
    })
}