React.js - 复选框的值不反映初始状态

时间:2017-06-09 03:01:32

标签: javascript reactjs checkbox components

我正在使用以下代码渲染复选框:

export default class Day extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            startTime: this.props.startTime,
            endTime: this.props.endTime,
            available: this.props.available
        }
        console.log(this.state.available)
    }

    return (
        <div className='day'>
            <label className='name'>
                {day.name}
                <input
                    type='checkbox'
                    checked={this.state.available}
                    onChange={this.handleAvailableChange}
                    />
            </label>
            {this.state.available}

        </div>
    );
}

Day组件从父组件呈现,如下所示:

export default class Schedule extends React.Component {

    render () {
        const dayComponents = this.props.days.map( (day) =>
            <Day key={day.id}
                startTime={this.state[day.name].start}
                endTime={this.state[day.name].end}
                available={this.state[day.name].available}
                day={day}
                handleDayChange={(day, startOrEnd, time, available) => this.handleDayChange(day, startOrEnd, time, available) }
            />

        return (
            <div>
                {dayComponents}
            </div>
        );
    }
}

...其中this.props.days是一个天体对象数组,如下所示:

#<Day id: 14, name: "Saturday">

一个看起来像这样的州:

{"Sunday": {"start": 0, "end": 0, "available": true},
"Monday": {"start": 0, "end": 0, "available": true},
etc...}

我的复选框的值应该根据this.state.available的值进行初始化,但是在渲染组件时会检查每个复选框。

我正在两个不同的地方看this.state.available的价值,在这两个地方,我得到5个真实和2个谬误。

我在这里缺少组件生命周期的某些方面吗?我是否需要使用像getInitialState()这样的东西(当我尝试时没有改变任何东西)?

希望这是一个简单而愚蠢的东西我忽略了,因为它似乎是这样的基本功能......

编辑:

我已从Day组件中删除状态,并按以下方式呈现复选框:

<label className='name'>
    {day.name}
    <input
        type='checkbox'
        checked={this.props.available}
        onChange={this.handleAvailableChange}
        />
</label>
{this.props.available}

然而,这仍然是我得到的输出:

Screen cap

值得注意的是,如果我将静态false分配给checked的值,则会返回未选中的复选框。

编辑2(解决方案):

事实证明,当我将计划保存到我的数据库时(我从中提取available值),我将布尔值保存到字符串,因为AJAX请求中的参数被自动转换为不同的数据类型。

所以我试图将checked的值设置为"false",它总是返回true,因为它是一个存在的字符串。

1 个答案:

答案 0 :(得分:0)

由于您通过父组件管理state,我建议您不要再次在子组件中存储值,直接使用this.props.keyName。您也传递了更改function,使用该方法更新父state值,更新父state后,更新的值将自动传递给子组件。在re-render,它将反映ui中的所有更改。

检查此工作代码段:

let days = [
    {name:"Sunday"}, 
    {name:"Monday"},
    {name:"Tuesday"},
    {name:"Wednesday"},
    {name:"Thursday"},
    {name:"Friday"},
    {name:"Saturday"},
];

class Schedule extends React.Component {
    constructor(){
        super();
        this.state={
            "Sunday": {"start": 0, "end": 0, "available": true},
            "Monday": {"start": 0, "end": 0, "available": true},
            "Tuesday": {"start": 0, "end": 0, "available": true},
            "Wednesday": {"start": 0, "end": 0, "available": true},
            "Thursday": {"start": 0, "end": 0, "available": true},
            "Friday": {"start": 0, "end": 0, "available": false},
            "Saturday": {"start": 0, "end": 0, "available": false},
        }
    }
    
    handleDayChange(value, dayName){
       let obj = {...this.state[dayName]};
       obj.available = value;
       this.setState({[dayName]: obj});
    }

    render () {
        const dayComponents = this.props.days.map(day =>
            <Day 
                key={day.name}
                startTime={this.state[day.name].start}
                endTime={this.state[day.name].end}
                available={this.state[day.name].available}
                name={day.name}
                handleDayChange={(value, dayName) => this.handleDayChange(value, dayName) }
            />
        )
        return (
            <div>
                {dayComponents}
            </div>
        );
    }
}

class Day extends React.Component {
    constructor(props){
        super(props)
        this.state = {
        }
        this.handleAvailableChange = this.handleAvailableChange.bind(this);
    }

    handleAvailableChange(e){
        this.props.handleDayChange(e.target.checked, this.props.name);
    }

    render(){
        let values = this.props;
        return (
            <div className='day'>
                <label className='name'>
                    {values.name}
                    <input
                        type='checkbox'
                        checked={values.available}
                        onChange={this.handleAvailableChange}
                    />
                </label>
                {values.available + ""}
            </div>
        );
    }
}

ReactDOM.render(<Schedule days={days}/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>