简体   繁体   中英

How to pass data to a form in ReactJS?

How do you pass data to a form to edit in ReactJS?

I have 3 components, Table, Form and a parent component.

return (
    <Table />
    <Form />
);

Table renders a list of items and each row has an Edit button

So, when the Edit button is clicked, it will call an edit function (passed from parent using props) with the id of the item.

this.props.edit('iAmTheIdOfTheItem');

The edit function will set the id in the parent component state.

edit = (id) => {
    this.setState({ id })
}

The selected item is passed to the Form component.

<Form item={ items.find(item => item.id === this.state.id) } />

This should store the current passed data in the Form component state. So that I can use that data to make any changes.

When the update button will be clicked, it will pass the state to the parent component.

Possible Solutions

  1. componentDidMount

I can't set the state using componentDidMount since the Form component is already mounted.

  1. id && < Form />

While this can help me use componentDidMount. But the problem is that the Form component is wrapped in a Modal component. So, closing animation will not work when I update the value and clear the id in the state.

  1. getDerivedStateFromProps

I can use this one as a last resort but it looks like a hack to me and I'm not sure if I really need this. Since I've more than 5 forms, adding this every form does not look good to me.

Any better approach? Suggestions?

This should be helpful https://codesandbox.io/s/82v98o21wj?fontsize=14

You can use Refs for this.

Reference the child using this.child = React.createRef() and pass this to your child component like this ref={this.child} . Now you can use that child's functions like this this.child.current.yourChildsFunction("object or data you want to pass") then on that child function, just set your form state using the data passed.

Here's a complete example. Sandbox HERE

class Parent extends Component {
  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onClick = () => {
    this.child.current.fillForm("Jackie Chan");
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>Click</button>
        <br />
        <br />
        <Child ref={this.child} />
      </div>
    );
  }
}

class Child extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    };
  }

  handleChange = ({ target }) => {
    this.setState({ [target.name]: target.value });
  };

  fillForm(passedvalue) {
    this.setState({ name: passedvalue });
  }

  render() {
    return (
      <form>
        <label for="name">Name</label>
        <input
          id="name"
          name="name"
          onChange={this.handleChange.bind(this)}
          value={this.state.name}
        />
      </form>
    );
  }
}

Here an updated version of your sandbox: https://codesandbox.io/s/jprz3449p9

The process is quite basic:

  • You send the edited item to your form (via props)
  • The form stores a copy in its own state
  • When you change the form, it changes the local form state
  • On submit, you send the state to your parent with a callback ( onUpdate here)

What you were missing:

  • Refresh the local form state when props change

    if (!item || id !== item.id) { this.setState(item); }
  • Notify the parent when the item is updated with a callback

    update = event => { event.preventDefault(); this.props.onUpdate(this.state); this.setState(emptyItem); };

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