0

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?

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the solution, why doesn't Application(props) re-render or re-run, each time I execute setContacts ?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.