Chen
Chen

Reputation: 970

React pass variables between functions

I have this React component that I am trying to build. addEntry detects when the user submits a data entry, and RenderTable should render each entry in a table row format:

import React, { useState, setState } from 'react';
import ReactDOM from 'react-dom'function 

function addEntry({ addEntryData }) {
  const data = [{
    First: "aaa",
    Last: "bbb",
    Phone: 123123
  }];
  const [contact, setContact] = useState(data);

  const submitEntry = (e) => {
    e.preventDefault();
    setContact(contact.push({
      First: e.target.userFirstname.value,
      Last: e.target.userLastname.value,
      Phone: e.target.userPhone.value
    }))
  }

  return (
    <form onSubmit={submitEntry} style={style.form.container}>
      <input 
        className='userFirstname'
        name='userFirstname' 
        type='text'
      />
      <input 
        className='userLastname'
        name='userLastname' 
        type='text' 
      />
      <input
        className='userPhone' 
        name='userPhone' 
        type='text'
      />
      <input 
        className='submitButton'
        type='submit' 
        value='Add User' 
      />
    </form>
  )
};

function RenderTable(props) {
  return (
    <table className='informationTable'>
      <thead> 
        <tr>
          <th style={style.tableCell}>First name</th>
          <th style={style.tableCell}>Last name</th>
          <th style={style.tableCell}>Phone</th>
        </tr>
      </thead> 
    </table>
  );
}

function Application(props) {
  return (
    <section>
      <addEntry/>
      <RenderTable/>
    </section>
  );

I would like to pass the contact data from addEntry to RenderTable, so RenderTable could generate some rows. But I have tried props or calling RenderTable(contact). Contact seems to live only inside addEntry, and not RenderTable. What should I do such that RenderTable could read the values stored in the contact variable?

Upvotes: 0

Views: 3765

Answers (2)

Branislav Lazic
Branislav Lazic

Reputation: 14806

There are few solutions to this problem. Probably the easiest one is to create a useState in Application component, pass the update function to addEntry (suggestion: name it AddEntry) and the state to RenderTable. Basically, move your state from addEntry to Application component. I presume that the table will contain list of contacts.

function Application(props) {
  const [contacts, setContacts] = useState([]);
  return (
    <section>
      <addEntry setContacts={setContacts}/>
      <RenderTable contacts={contacts}/>
    </section>
  );

And for addEntry add the prop setContacts:

function addEntry({ addEntryData, setContacts }) {
   const submitEntry = (e) => {
     e.preventDefault();
     setContacts((contacts) => [...contacts, {
       First: e.target.userFirstname.value,
       Last: e.target.userLastname.value,
       Phone: e.target.userPhone.value
     }])
   }
  ... 
}

Cleaner solution: Use some global state management library such as Redux or React context.

Upvotes: 5

Alex Yepes
Alex Yepes

Reputation: 1195

Time to start using some kind of global state management tool where you can handle the state among components. My suggestion to you is start by using Context to understand how it works, and later on, jump into Redux or Flux. If you decide not to use any of these tools, you are going to have to use props. Props are passed from parent component to child, so in your case, the component that holds AddEntry and RenderTable, Application in your case, will hold the state and other functions to modify the state. Then you need to pass the state and functions as props to the child components.

Upvotes: 0

Related Questions