Get form value from nested children using response.js

How to pass child state back to container? I have a very simple application, but due to the fact that I broke them into smaller components, now I am looping, passing the state (form) back to my container. I can also call api in the child component, and then get it through the props container, but this does not clear, I want the "final event" to be placed in the container, and the container has a "main" state.

Is my first intention (make sure the "main" state is stored in the container) correct? If so, how to return the state from the child component back to the container? Suppose I do not use reduction.

https://codesandbox.io/s/8zrjjz3yjj

+4
source share
2 answers

Pass the method as a property:

Parent:

class Parent extends Component {
    ....

    render = () => <Child onChange={childDidSomething}/>

    childDidSomething = state => {
        ...
    }
}

Child:

class Child extends Component {
    ....

    render() {...}

    somethingChanged() {
        this.props.onChange(this.state);
    }
}
+4
source

You must raise the state up .

Let the parent component deal with the state regarding its children, and pass the handlers to the children so that children can call them and pass them the appropriate values.

Here is an example of this approach with your code:

class AddUser extends React.Component {

  onChange = ({ target }) => {
    const { onChange } = this.props;
    onChange(target.value);
  }

  render() {
    return (
      <div>
        <input onChange={this.onChange}
          type='text' placeholder='user' />
      </div>
    )
  }
}

class Modal extends React.Component {

  state = { newUser: '' }

  onUserChange = newUser => this.setState({ newUser });

  addUser = () => {
    const { addUser } = this.props;
    const { newUser } = this.state;
    addUser(newUser);
    this.setState({ newUser: '' }); // reset the field
  }

  render() {
    return (
      <div>
        <AddUser onChange={this.onUserChange} />
        <button onClick={this.addUser}>add</button>
      </div>
    )
  }
}

class MainContainer extends React.Component {

  state = {
    showAddUser: false,
    users: [{
      name: 'Jane'
    }, {
      name: 'Black'
    }]
  }

  addUserIntoUsers = (userName) => {
    const { users } = this.state;
    if (userName) { // only if we have a value
      const nextUsers = [...users, { name: userName }];
      this.setState({ users: nextUsers, showAddUser: false });
    }
  }

  render() {
    return (
      <div>
        <button onClick={() => this.setState({ showAddUser: !this.state.showAddUser })}>
          Toggle User Panel
        </button>
        <br />
        {this.state.users.map(o => {
          return (<div>{o.name}<br /></div>)
        })}
        {this.state.showAddUser && <Modal addUser={this.addUserIntoUsers} />}
      </div>
    )
  }
}

ReactDOM.render(<MainContainer />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Run code
+1
source

Source: https://habr.com/ru/post/1692354/


All Articles