How to transfer a state from a component to another?

Viewed 69

I have a form which takes name, age and gender as user input. When the submit button is clicked I want to transfer the state of the form to App.js where I can add the state to the array with users. How can I transfer the state from Form.js to App.js?

//Form.js

export const Form = ({ onClick }) => {
  const [form, setForm] = useState({
    name: "william",
    age: 31,
    gender: "male",
  });
  return <div><input type="submit" onClick={onClick}/></div>;
};

//App.js

export const App = () => {
  const [users, setUsers] = useState({
    name: "Anna",
    age: 24,
    gender: "female",
  });

  function addUser(e) {
    e.preventDefault();
  }
  return (
    <div>
      <Form onClick={addUser} />
    </div>
  );
};
2 Answers

You need to pass a function down to the form component that takes the new user as an argument:

//Form.js
import React, { useState } from 'react';

export const Form = ({ onClick }) => {
  const [form, setForm] = useState({
    name: "william",
    age: 31,
    gender: "male",
  });
  return <div>
    <input type="submit" onClick={() => onClick(form)}/>
  </div>;
};

//App.js

export const App = () => {
  const [users, setUsers] = useState([{
    name: "Anna",
    age: 24,
    gender: "female",
  }]);

  function addUser(newUser) {
    setUsers([...users, newUser]);

  }
  return (
    <div>
      <Form onClick={(newUser) => addUser(newUser)} />
    </div>
  );
};

In your onClick you call that function and pass in the new user. This addUser function spreads the users that you already have in the state of App into a new array and then adds the new user to it. Note that you need an array to keep track of multiple users - you just an object before.

Hope that makes sense!

ReactJS is a uni-directional framework.

Unidirectional data flow is a technique that is mainly found in functional reactive programming. It is also known as one-way data flow, which means the data has one, and only one way to be transferred to other parts of the application. In essence, this means child components are not able to update the data that is coming from the parent component. In React, data coming from a parent is called props

If you are trying to make the data flow, the other way, this is not the right approach and that means there is a better way available.

You can achieve this by useRef but while scaling your application , you can run into trouble due to this flaw.

/Form.js
import React, { useState } from 'react';

export const Form = ({ onClick }) => {
  const [form, setForm] = useState({
    name: "william",
    age: 31,
    gender: "male",
  });
  return <div>
    <input type="submit" onClick={() => onClick(form)}/>
  </div>;
};

//App.js

export const App = () => {
const ref = React.createRef();
  const [users, setUsers] = useState([{
    name: "Anna",
    age: 24,
    gender: "female",
  }]);

  function addUser(newUser) {
    setUsers([...users, newUser]);

  }
  return (
    <div>
      <Form ref={ref} onClick={(newUser) => addUser(newUser)} />
    </div>
  );
};

Now through ref you have a reference of the child component in the parent component. You can put any event listener on it and it will work.

Related