子组件未在道具更新时更新

时间:2019-03-12 14:42:24

标签: javascript reactjs

我在更新我的孩子组件时遇到了一些麻烦。我的SettingsForm组件使用Switch子组件。

Switch接受updateValue方法作为道具,并使用它来更新父组件中on道具的值。由于某种原因,on属性值无法传播到孩子。初始加载时,组件会正确设置,但此后它再也不会反映父级的更改。我可以进行控制台操作,并查看父级中的值已更改,但子级从未更新。

我以前在类组件中使用过此子组件,并且工作正常。功能组件出现问题。

SettingsForm.js

import React, { useState } from 'react'

import { Input, Label } from 'reactstrap'
import Switch from '../../../../components/Input/Switch/Switch'

export default function SettingsForm ({ settingOne, settingTwo, enabled, updateSettings}) {
    const [settings, setSettings] = useState({
        settingOne: settingOne,
        settingTwo: settingTwo,
        enabled: enabled
    })

    /**
     * Update values for select inputs
     * 
     * @param {event} event 
     */
    const updateSwitch = (event) => {
        const name = event.target.name
        const value = event.target.checked

        settings[name] = value
        setSettings(settings)
    }

    return (
        <div className={"settings-form"}>
            <div className="row">
                <div className="col-sm">
                    <div className="row">
                        <div className="col-sm-1">
                            <Switch                
                                id={'settingOne'}
                                name={'settingOne'}
                                value={settingOne}
                                on={settingOne}
                                updateValue={updateSwitch}/>
                        </div>
                        <div className="col-sm-10">Turn Setting One On</div>
                    </div>
                    <div className="row">
                        <div className="col-sm-1">
                            <Switch        
                                id={'settingTwo'}
                                name={'settingTwo'}
                                value={settingTwo}
                                on={settingTwo}
                                updateValue={updateSwitch}/>
                        </div>
                        <div className="col-sm-10">Turn Setting Two On</div>
                    </div>
                </div>
                <div className="col-sm">
                    <div className="row">
                        <div className="col-sm-1">
                            <Switch                                                     
                                name={'enabled'}
                                value={enabled}
                                id={'enabled'}
                                on={enabled}
                                updateValue={updateSwitch}/>
                        </div>
                        <div className="col-sm-10">Enable Item</div>
                    </div>
                </div>
            </div>
            <div className="row">
                <div className="col">
                    <button type="button" onClick={updateSettings(settings)}>Update Settings</button>
                </div>
            </div>
        </div>
    )
}

Switch.js

import React, { Component } from 'react';
import style from './switch.css';

class Switch extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <React.Fragment>
                <label className={style.switch}>
                    <input
                        type="checkbox"
                        name={this.props.name}
                        id={this.props.id}
                        onClick={this.props.updateValue}
                        checked={this.props.on}
                        onChange={() => {}}
                    />
                    <span className={style.slider + ' ' + style.round}></span>
                </label>
            </React.Fragment>
        )
    }
}

export default Switch;

1 个答案:

答案 0 :(得分:1)

通过更改settings对象,React认为在您调用setSettings时它没有被更新。

您可以改为创建settings对象的副本,并使用该对象更新状态。

const updateSwitch = event => {
  const { name, value } = event.target;
  const newSettings = { ...settings, [name]: value };
  setSettings(newSettings);
};