简体   繁体   中英

Parent State not updating when passed data from child component

I'm trying to create a note-taking application in React. The application should add a new note when an "Add note" button is pressed with the value in the input box.

Unfortunately when I try to push the note to the list and update the parents state the changes aren't reflected on screen or in the react debugger.

The pushing of new note to list can be seen in the alert line but not anywhere else.

Here is the parent component containing the original notes state:

class NoteApplication extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            notes: Array(),
        };
        this.update = this.update.bind(this);
        this.state.notes.push("Sample note");


    }

    update(notes) {
        return () => {
            this.setState({
              notes: notes
            });
         }
    }

    render() {
        return (
            <div>
                <h1>React Notes</h1>
                <div class="InsertBarDiv">
                    <InsertBar 
                    notes={this.state.notes}
                    update = {this.update}
                    />   
                </div>
                <div class="NotesDiv">
                    <Notes 
                    notes={this.state.notes}
                    />
                </div>
            </div>
        )
    }
}

And here is the child component

class InsertBar extends React.Component {

    constructor(props) {
        super(props);
        this.state = {value:''};

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({value: event.target.value});
    }

    handleSubmit(event) {
        const notes = this.props.notes.slice();
        notes.push(this.state.value);
        this.props.update(notes);
        alert(notes);
        event.preventDefault();
    }

    render() {
        return (
            <div>
                <form onSubmit={this.handleSubmit}> 
                    <input class="noteInsertBar" type="text" name="" onChange={this.handleChange}/>
                    <input class="insertBut" type="submit" value="Add Note"/>
                </form>
            </div>

        )
    }
}
class Notes extends React.Component {

    renderNote(i) {
        return (
            <div>
                {this.props.notes}
            </div>

        )
    }

    render() {
        return (
            <div>
                <h2>Notes:</h2>
                <div class="FullNote">
                    {this.renderNote(1)}
                </div>
            </div>
        )
    }
}

I would expect the note to be pushed to the copy of the notes list & the parents state to be set to the new copy of the notes list.

I would then expect this to be displayed onscreen.

I got some help in the react discord thanks to the user @WasaWasaWassup so I'd like to share what fixed my issue.

Mutating the parent state in the constructor to add a sample note was causing issues.

The second issue was my update function returning a function yet being called as if it wasn't.

Removing the constructor mutating & altering my update function to just set the state without an embedded function fixed all my issues and the notes array updates and displays correctly.

It's likely due to the fact that you're returning a function from update , you should just call setState when update gets called:

update(notes) {
  setState({ notes });
}

Side note: You should avoid Array.push when dealing with arrays in React. The way you're doing it is fine because you're calling slice to copy the array before you push, but if you use concat or the spread operator, you'll be less likely to unintentionally introduce bugs.

const notes = this.props.notes.concat(this.state.value);

or:

const notes = [...this.props.notes, this.state.value];

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