3
\$\begingroup\$

I have a Parent and a Child class, each with their own state. The Parent maintains an array of children saving their values from their state.

React 101 says that I should lift the state up from the child and set the array from there. There's also this question that asks how to access child's state on SO, with a popular answer that suggest Refs could be used. However the docs say Refs should be used (sparingly) for accessing elements, not state.

So I've come up with what I think is half way between lifting state up, and passing props down. The intent being that it reduces clutter in the Parent state:

//Parent Component
import React, { Component } from 'react';

class Parent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            field1: '',
            field2: '',
            children: [],
        };
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({[name]: value});
    }

    // Push children into the Parent's array
    handleAddChild(child) {
        this.setState((prevState) => ({
            children: [...prevState.children, child]
        }));
    }

    render() {
        return (
            <form>
                <div>
                    <input name="field1" type="number" value={this.state.field1} onChange={this.handleChange} />
                </div>
                <div>
                    <input name="field2" type="number" value={this.state.field2} onChange={this.handleChange} />
                </div>
                <input name="save" type="button" value="save" onClick={this.handleSave} />
            </form>
            <div>

                //Pass the addChild method down through props
                <Child onSave={this.handleAddChild} />
            </div>
        );
    }
}


// Child Component
import React, { Component } from 'react';

class Child extends Component {
    constructor(props) {
        super(props);
        this.state = {
            field3: '',
            field4: '',
        };
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({[name]: value});
    }

    handleSave(event) {

        // Pass the state up to the Parent
        this.props.onSave(this.state);
    }

    render() {
        return (
            <form>
                <div>
                    <input name="field3" type="number" value={this.state.field3} onChange={this.handleChange} />
                </div>
                <div>
                    <input name="field4" type="number" value={this.state.field4} onChange={this.handleChange} />
                </div>
                <input name="save" type="button" value="save" onClick={this.handleSave} />
            </form>
        );
    }
}

Is this an acceptable way to access a child's state? Am I going to run into any issues doing it this way?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.