Home > Mobile >  How to trigger a function of sibling component in React?
How to trigger a function of sibling component in React?

Time:04-14

I am new to front end world and could not figure out how to trigger a function from a sibling component. Lets say I have 2 component in App.js. The page is: enter image description here

function App() {
  return (
    <div className="App">
      <h1>Customer List</h1>
      <MainPanel/>
      <TableFooterPanel/>
    </div>
  );
}

MainPanel code is:

function MainPanel() {

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

  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>
          {customers &&
            customers.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>
  );
}

export default MainPanel;

And TableFooterPanel code is:

function TableFooterPanel() {

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

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

    }

    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;

What I want to do is, whenever I click button and send the customer info to backend to save then immediately call a function in MainPanel to set it's table data and update the table immediately after adding. Something like, I want to click button and add it and if response is success then refresh the table (without refreshing whole page).

What is the best way to do that ?

CodePudding user response:

In React we have one data flow. From parent to children, and there is no way to pass some information, from children to parent/sibling. What you want is called Lifting State Up

Just put necessary logic to parent component, here it will be the App component. In App component you will have a function which triggers table data loading, and when data will be loaded you should save it, also inside the App component. You will pass table data to MainPanel as prop. Then pass a that function from App component (which triggers table data loading) to your TableFooterPanel component and call it when onClick event happens.

CodePudding user response:

I would introduce a component to hold both the table and the footer, and put the state in this component. Then you pass a function as a prop down to the footer component, which will update the table data. Then you pass the table data as props to the table component.

function Customers({initialData = []}) {
  const [customers, setCustomers] = useState(initialData);

  return (
    <div>
      <h1>Customers</h1>
      <CustomerTable customers={customers} />
      <TableFooter addCustomer={(customer) => setCustomers([...customers, customer])} />
    </div>
  )
}

By setting initialData to default to an empty array, you can rely on array methods like .map in the table component.

  • Related