Home > Mobile >  How to set data in child component dynamically by using props in React?
How to set data in child component dynamically by using props in React?

Time:04-14

I have solved one of my problem in this question for passing function as param

Now I am sending request to backend to add new record to db and I want to update the table immediately after adding new record by getting all items from backend.

Here is my parent App.js class having 2 component as MainPanel and TableFooterPanel:

function App() {

  const [customers, setCustomers] = useState([]);
  
  useEffect(() => {
    const fetchPostList = async () => {
      const response = await service.getCustomerList();
      setCustomers(response.data);
    };
    fetchPostList()
  }, []);

  const refreshTableData = () => {
    const fetchPostList = async () => {
      const response = await service.getCustomerList();
      setCustomers(response.data);
    };
    fetchPostList()
  }
  return (
    <div className="App">
      <h1>Customer List</h1>
      <MainPanel param={customers}/>
      <TableFooterPanel funcParam={refreshTableData}/>
    </div>
  );
}

export default App;

I am passing refresh function to TableFooterPanel which has a button to add new record and this function is triggered when a new record is added. Here is TableFooterPanel

function TableFooterPanel(props) {

    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');

    const addNewCustomer = (name, surname) => {
        service.addCustomer(name, surname);
        props.funcParam();
    }

    return (

        <>
            <Card className='buttonFooter'>
                <Form className='buttonFooter'>
                    <input type="text" placeholder="First Name" defaultValue={firstName} onChange={e => setFirstName(e.target.value)}></input>
                    <input type="text" placeholder="Last Name" defaultValue={lastName} onChange={e => setLastName(e.target.value)}></input>
                    <Button onClick={() => addNewCustomer(firstName, lastName)}>Add</Button>
                </Form>
            </Card>

        </>

    );

}
export default TableFooterPanel;

And I want to refresh table data which lies in MainPanel:

function MainPanel(props) {

  const [customers, setCustomers] = useState([]);
  
  const deleteCustomer = (id) => {
    service.deleteCustomerById(id);
  }

  return (
    <ReactBootStrap.Table striped bordered hover>
        <thead>
          <tr>
            <th>ID</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Delete</th>
          </tr>
        </thead>
        <tbody>
          {props.param &&
            props.param.map((item) => (
              <tr key={item.id}>
                <td>{item.id}</td>
                <td>{item.firstName}</td>
                <td>{item.lastName}</td>
                <td><Button onClick={() => deleteCustomer(item.id)} ><FontAwesomeIcon icon={faTrashRestore} /></Button></td>
              </tr>   
            ))}
        </tbody>
      </ReactBootStrap.Table>
  );
}

What happens here is when I add a new record, the table data is not changing dynamically, but if I add second data then I sees the previous data and updating table but still not showing the last added data. How can I refresh data and send latest data to MainPanel?

export default MainPanel;

CodePudding user response:

Your problem is with this section:

const addNewCustomer = (name, surname) => {
  service.addCustomer(name, surname);
  props.funcParam();
}

It looks like you are calling the refresh function (props.funcParam()) before the addCustomer service is finished being called (since this is a Promise). That is causing your fetch to start fetching the existing data BEFORE it is updated.

You'll need to make the function asynchronous and then await it like this:

const addNewCustomer = async (name, surname) => {
  await service.addCustomer(name, surname);
  props.funcParam();
}

Now your function will wait for service.addCustomer to finish executing before executing the refresh fuction.

CodePudding user response:

Assuming service.addCustomer(name, surname) is an async call and it posts data to server. Then you need to put addNewCustomer method into an async and await for the response of this call, once you get the response, you need to call props.funcParam() to get the latest data from server.

  • Related