React setState在同一个状态对象上多次调用

时间:2017-01-12 13:20:24

标签: reactjs

我有以下内容:

import React from 'react';
import ReactDOM from 'react-dom'
import {render} from 'react-dom';

import Forms from './forms/forms.jsx';

class Option1 extends React.Component {
    render () {
        return (
            <p>Icon 1</p>
        )
    }
}

class TShirt extends React.Component {
    render () {
        console.log(this.props.currentState);
        return <div className="thsirt">
                    <h1>{this.props.name}</h1>
                    <p>{this.props.iconID}</p>
                    {this.props.optionA ? <Option1  /> : ''}
                </div>;
    }
}

class Link extends React.Component {
    render () {
        return (
            <li 
                data-id={this.props.el}
                onClick={this.props.onClick} 
                className={this.props.activeClass}>{this.props.el}
            </li>
        );
    }
}

class Nav extends React.Component {
    getComponentID (id) {
        switch(id) {
            case 'name':
                return 1;
                break;
            case 'color':
                return 2;
                break;
            case 'design':
                return 3;
                break;
            case 'share':
                return 4;
                break;
        }
    }
    handleClick (event) {
        // setting active class
        var id = event.target.getAttribute("data-id"); 
        this.props.action(id);

        // switching coomponent based on active class
        var component = this.getComponentID(id);
        this.props.switchComponent(component);
    }
    render () {
        var links = ['name', 'color', 'design', 'share'],
            newLinks = [],
            that = this;
        links.forEach(function(el){
            newLinks.push(<Link 
                            onClick={that.handleClick.bind(that)} 
                            activeClass={that.props.active == el ? 'active': ''} 
                            key={el} 
                            el={el} 
                          />
            );
        });
        return (
            <ol>
                {newLinks}
            </ol>
        );
    }
}

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: '',
            color: '',
            active: '',
            formId: 1,
            optionA: {
                on: false,
                icon_id: '',
                option_id: '',
                name: ''
            }
        };
        this.setName = this.setName.bind(this);
        this.setColor = this.setColor.bind(this);
        this.setAtciveNavEl = this.setAtciveNavEl.bind(this);
        this.setFormId = this.setFormId.bind(this);

        this.setOptionA = this.setOptionA.bind(this);
        this.setOptionAVisibility = this.setOptionAVisibility.bind(this);
    }
    setName (tshirt) {
        this.setState({ name:tshirt })
    }
    setColor (color) {
        this.setState({ color:color })
    }
    setAtciveNavEl (el) {
        this.setState({ active:el })
    }
    setFormId (id) {
        this.setState({ formId:id })
    }

    setOptionA (iconID, iconName) {
        this.setState({ 
            optionA: 
            {
                icon_id: iconID,
                name: iconName
            } 
        })
    }
    setOptionAVisibility (onOff, optionID) {
        this.setState({ 
            optionA: 
            {
                option_id: optionID,
                on: onOff
            }
        })
    }
    render () {
        return (
            <section className={this.state.color}>
                <Nav 
                    active={this.state.active} 
                    action={this.setAtciveNavEl} 
                    switchComponent={this.setFormId} 
                />
                <TShirt 
                    name={this.state.name}
                    icons={this.state.options}

                    optionA={this.state.optionA.on}
                    currentState={this.state}
                />
                <Forms 
                    name={this.state.name} 
                    action={this.setName} 
                    colorVal={this.setColor} 
                    activeNav={this.setAtciveNavEl} 
                    switchComponent={this.setFormId}
                    formID={this.state.formId}

                    setOptionA={this.setOptionA}
                    setOptionAVisibility={this.setOptionAVisibility}
                />
            </section>
        );
    }
}

render(<App/>, document.getElementById('app'));

我需要在不同时间填充此对象:

    setOptionA (iconID, iconName) {
        this.setState({ 
            optionA: 
            {
                icon_id: iconID,
                name: iconName
            } 
        })
    }
    setOptionAVisibility (onOff, optionID) {
        this.setState({ 
            optionA: 
            {
                option_id: optionID,
                on: onOff
            }
        })
    }

我遇到的问题是我在控制台时记录我的状态:

class TShirt extends React.Component {
    render () {
        console.log(this.props.currentState);
        return <div className="thsirt">
                    <h1>{this.props.name}</h1>
                    <p>{this.props.iconID}</p>
                    {this.props.optionA ? <Option1  /> : ''}
                </div>;
    }
}

在我的所有点击事件之后,似乎我从optionA对象中松开了“on”和“option_id”。 在同一个对象上调用setState是否会覆盖以前的setState?

1 个答案:

答案 0 :(得分:1)

如果您正在编写ES2015,可以使用spread operator复制整个对象,只需修改其中一个属性:

setOptionAVisibility (onOff, optionID) {
    this.setState({ 
        optionA: 
        {
            ...this.state.optionA,
            option_id: optionID,
            on: onOff
        }
    })
}

在状态树上修改复杂对象的单个属性时非常有用。