admin管理员组

文章数量:1389920

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

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 ?

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

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 ?

Share asked Apr 14, 2022 at 10:43 abidinberkayabidinberkay 2,0355 gold badges49 silver badges78 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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 ponent, here it will be the App ponent. In App ponent you will have a function which triggers table data loading, and when data will be loaded you should save it, also inside the App ponent. You will pass table data to MainPanel as prop. Then pass a that function from App ponent (which triggers table data loading) to your TableFooterPanel ponent and call it when onClick event happens.

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

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 ponent.

本文标签: javascriptHow to trigger a function of sibling component in ReactStack Overflow