Gabriela Moura
Gabriela Moura

Reputation: 53

Passing data from one component to the another

I am new to React and I’m trying to understand how to pass data from one component to the another. I don't know what I am doing wrong. In my example below I thought returning state in the Form component would be enough to use this data in the Users list, but it’s not. Can someone explain how to do this?

function Form({ add }) {
  const [state, setState] = useState({ add });
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [phone, setPhone] = useState(0);

  const addUser = () => {
    setState({
      firstName: firstName,
      lastName: lastName,
      phone: phone,
    });
    return state;
  };

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
      }}
    >
      <h1>Team Management</h1>
      <label>First name:</label>
      <br />
      <input
        className="userFirstname"
        name="userFirstname"
        type="text"
        placeholder="First Name"
        onChange={(event) => {
          setFirstName(event.target.value);
        }}
      />
      <br />
      <br />
      <label>Last name:</label>
      <br />
      <input
        className="userLastname"
        name="userLastname"
        type="text"
        placeholder="Last Name"
        onChange={(event) => {
          setLastName(event.target.value);
        }}
      />
      <br />
      <br />
      <label>Phone:</label>
      <br />
      <input
        className="userPhone"
        name="userPhone"
        type="text"
        placeholder="555555555"
        onChange={(event) => {
          setPhone(event.target.value);
        }}
      />
      <br />
      <br />
      <input
        className="submitButton"
        type="submit"
        value="Add member"
        onClick={addUser}
      />
      <hr />
    </form>
  );
}

function Users(props) {
  console.log("props", props); //empty
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Phone</th>
          </tr>
          <tr>
            <td> {props.firstName} </td>
            <td> {props.lastName} </td>
            <td> {props.phone} </td>
          </tr>
        </thead>
      </table>
    </>
  );
}

function Application(props) {
console.log('props', props); //empty
Users
  return (
    <section>
      <Form />
      <Users value={props} />
    </section>
  );
}

export default Application;

Thanks a lot!

Upvotes: 1

Views: 75

Answers (3)

Eduardo Rosostolato
Eduardo Rosostolato

Reputation: 858

To communicate between components you should pass a function defined on the parent component and pass it as a parameter. What you did with the add method, it doesn't make sense to set it on useState, you just need to use it as a normal function.

Here is the same example but with some changes to make it work:

function Form({ add }) {
  // const [state, setState] = useState({ add });
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [phone, setPhone] = useState(0);

  const addUser = () => {
    // setState({
    add({
      firstName: firstName,
      lastName: lastName,
      phone: phone
    });
    // return state;
  };

  return (
    <form
      onSubmit={e => {
        e.preventDefault();
      }}
    >
      <h1>Team Management</h1>
      <label>First name:</label>
      <br />
      <input
        className="userFirstname"
        name="userFirstname"
        type="text"
        placeholder="First Name"
        onChange={event => {
          setFirstName(event.target.value);
        }}
      />
      <br />
      <br />
      <label>Last name:</label>
      <br />
      <input
        className="userLastname"
        name="userLastname"
        type="text"
        placeholder="Last Name"
        onChange={event => {
          setLastName(event.target.value);
        }}
      />
      <br />
      <br />
      <label>Phone:</label>
      <br />
      <input
        className="userPhone"
        name="userPhone"
        type="text"
        placeholder="555555555"
        onChange={event => {
          setPhone(event.target.value);
        }}
      />
      <br />
      <br />
      <input
        className="submitButton"
        type="submit"
        value="Add member"
        onClick={addUser}
      />
      <hr />
    </form>
  );
}

function Users({ users }) {
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Phone</th>
          </tr>
          {users.map(user => (
            <tr>
              <td> {user.firstName} </td>
              <td> {user.lastName} </td>
              <td> {user.phone} </td>
            </tr>
          ))}
        </thead>
      </table>
    </>
  );
}

export default function App() {
  const [users, setUsers] = useState([]);
  const addUser = user => setUsers([...users, user]);
  return (
    <section>
      <Form add={addUser} />
      <Users users={users} />
    </section>
  );
}

You can see it on stackblitz: https://stackblitz.com/edit/react-cehone

Upvotes: 1

Suleman Ahmad
Suleman Ahmad

Reputation: 484

You are passing props to User component but I think you didn't verify that those props have some value in them. Try to console props before passing them to Users component.

function Application(props) {
console.log('props', props); //if you are getting here then pass to Users
return (
  <section>
   <Form />
   <Users value={props} /> //If not getting props then pass string like 'props' to see that in Users component where you console the props
  </section>
 );
 }

Now check console when Users component renders

function Users(props) {
console.log("props", props); //now check here when it renders 
 return (
 //your render data
 );
 }

Also why are you using setState in addUser function when you are using useState Hook. Use second parameter you got in useState hook to set the state.

Upvotes: 0

Rahul Raj
Rahul Raj

Reputation: 516

You pass value as a props but you are not getting data from value I think it might work.

function Users(props) {
  console.log("props", props); //nothing here
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Phone</th>
          </tr>
          <tr>
            <td> {props.value.firstName} </td>
            <td> {props.value.lastName} </td>
            <td> {props.value.phone} </td>
          </tr>
        </thead>
      </table>
    </>
  );
}

or You can just pass value instead of props

function Users({value}) {
  console.log("props", props); //nothing here
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Phone</th>
          </tr>
          <tr>
            <td> {value.firstName} </td>
            <td> {value.lastName} </td>
            <td> {value.phone} </td>
          </tr>
        </thead>
      </table>
    </>
  );
}

function Application(props) {
  return (
    <section>
      <Form />
      <Users value={props} />
    </section>
  );
}

export default Application;

Upvotes: 0

Related Questions