Casebash
Casebash

Reputation: 118922

Is it okay to call setState on a child component in React?

I have some text. When you click on that element a modal pops up that lets you edit that text. The easiest way to make this work is to call setState on the child to initialise the text.

The other way, although more awkward, is to create an initial text property and make the child set it's text based on this.

Is there anything wrong with directly calling setState on the child or should I use the second method?

Upvotes: 4

Views: 2598

Answers (3)

Jason Warta
Jason Warta

Reputation: 450

It seems that your modal doesn't need to have its own state, in which case you should use a stateless React component.

This is one way of passing the data around your app in the React way.

class ParentComponent extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            initialText: "hello",
        }

        this.saveChildState = this.saveChildState.bind(this);
    }

    saveChildState(input) {
        console.log(input);
        // handle the input returned from child
    }

    render() {
        return (
            <div>
                <ChildComponent 
                    initialText={this.state.initialText} 
                    save={this.saveChildState} 
                />
            </div>
        );
    }
}

function ChildComponent(props) {
    return (
        <div>
            <input id="textInput" type="text" defaultValue={props.initialText}>
            </input>
            <button onClick={() => props.save(document.getElementById('textInput').value)}>
                Save
            </button>
        </div>
    )
}

Upvotes: 1

Andrew
Andrew

Reputation: 7555

Maybe I am misinterpreting your question, but I think it would make the most sense to keep the modal text always ready in your state. When you decide to show your modal, the text can just be passed into the modal.

class Test extends Component {
  constructor() {
    this.state = {
      modalText: 'default text',
      showModal: false
    }
  }
//Include some method to change the modal text
  showModal() {
    this.setState({showModal: true})
  }

  render(
    return (
      <div>
        <button onClick={() => this.showModal()}>
          Show Modal
        </button>
        { this.state.showModal ? <Modal text={this.state.modalText}/> : null }
      </div>
    )
  )
}

Upvotes: 0

Carlo
Carlo

Reputation: 652

Although it is recommended to keep the data of your react application "up" in the react dom (see more here https://reactjs.org/docs/lifting-state-up.html), I don't see anything wrong with the first aproach you mentioned.

If you have to store data that is very specific of a child I don't see anything wrong in keep that information in the child's state.

Upvotes: 2

Related Questions