简体   繁体   中英

Child component not updating on props update

I'm having a little trouble updating the my child component in react. I have my SettingsForm component that uses a Switch child component.

Switch accepts updateValue method as a prop and uses that to update the value for the on prop in the parent component. For some reason the on prop value isn't propagating through to the child. On initial load the component sets properly but after that it never reflects changes in the parent. I can console and see the values in the parent being changed but the child never updates.

I've used this child component in a class component before and it works fine. Having issues in a function component.

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;

By mutating the settings object, React doesn't think it has been updated when you call setSettings .

You can instead create a copy of the settings object and update your state with that.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM