Home > Software engineering >  onClick load react component in the same place
onClick load react component in the same place

Time:04-15

I have a panel with 3 buttons, i want to make onclick on every button, a different component will appear in the same place. How can this logic be done?

<AddNotification />
<EditNotification />
<DeleteNotification />
const AdminPanel = () => {
   
  return (
    <Card className={classes.input}>
        <div><h1>Notification Panel</h1></div>
        <form>
        <div className="form-group">
            <Button type="submit">Add Notification</Button>
        </div>
        <div className="form-group">  
           <Button type="submit">Edit Notification</Button>
        </div>
        <div className="form-group">  
            <Button type="submit">Delete Notification</Button>
        </div>
        </form>
    </Card>
  )
}

CodePudding user response:

Try this if you want to display one component at a time and hide the others when you click a button

const AdminPanel = () => {
  const [componentToDisplay, setComponentToDisplay] = useState("")
  
  return (
    <>
      <Card className={classes.input}>
        <div><h1>Notification Panel</h1></div>
        <form>
          <div className="form-group">
            {componentToDisplay !== "add ? (
              <Button type="submit" onCLick={() => setComponentTodisplay("add")}>Add Notification</Button>)
               :(<AddNotification />)}
          </div>
          <div className="form-group">  
             {componentToDisplay !== "edit ? (
              <Button type="submit" onCLick={() => setComponentTodisplay("edit")}>Edit Notification</Button>)
               :(<EditNotification />)}
          </div>
          <div className="form-group">  
            {componentToDisplay !== "delete ? (
              <Button type="submit" onCLick={() => setComponentTodisplay("delete")}>Delete Notification</Button>)
               :(<DeleteNotification />)}
          </div>
        </form>
      </Card>
    </>
  )
}

Or if you want to be able to replace every buttons, use this logic with one state per button

const AdminPanel = () => {
  const [addNotif, setAddNotif] = useState(false)
  const [editNotif, setEditNotif] = useState(false)
  const [deleteNotif, setDeleteNotif] = useState(false)
  
  return (
    <>
      <Card className={classes.input}>
        <div><h1>Notification Panel</h1></div>
        <form>
          <div className={`form-group ${editNotif || deleteNotif ? "display: none" : "display: flex"}`}>
            {!addNotif ? (
              <Button type="submit" onCLick={() => setAddNotif(true)}>Add Notification</Button>)
               :(<AddNotification setAddNotif={setAddNotif} />)}
          </div>
          <div className={`form-group ${addNotif || deleteNotif ? "display: none" : "display: flex"}`}>  
             {!editNotif ? (
              <Button type="submit" onCLick={() => setEditNotif(true)}>Edit Notification</Button>)
               :(<EditNotification setEditNotif={setEditNotif} />)}
          </div>
          <div className={`form-group ${addNotif || editNotif ? "display: none" : "display: flex"}`}> 
            {!deleteNotif ? (
              <Button type="submit" onCLick={() => setDeleteNotif(true)}>Delete Notification</Button>)
               :(<DeleteNotification setDeleteNotif={setDeleteNotif} />)}
          </div>
        </form>
      </Card>
    </>
  )
}

Then in your component

const AddNotification = ({setAddNotif}) => {
  ...
  return (
    ...  
      <button onCLick={() => setAddNotif(false)}>back</button>
    ...
  )
}

Same logic for the other components

CodePudding user response:

To achieve this logic you need to manage which component is displayed using a state.

This means:

  1. Attribute an arbitrary id to each component.
  2. Store the id of the active component in a useState hook.
  3. Use conditional rendering to display the component that match the current state.
  4. Update the state to the corresponding Id when clicking on each button.

A small example


const [activePanel, setActivePanel] = React.useState(0)

let currentPanel = <Panel0 />

  switch(activePanel){
     case 0:
      currentPanel = <PanelO />
     case 1:
      currentPanel = <Panel1 />
      // Continue as needed
  }

  return (

   <div>
    <CurrentPanel/>
    <button onClick={() => setActivePanel (0)}> Panel 0 </button>
<button onClick={() => setActivePanel (1)}> Panel 1 </button>
   // And so on
   </div>

 )

You can further refine this by extracting the switch statement into its own component that takes the activePanel as a prop.

CodePudding user response:

@MLDC No i don't have another divs, i want to replace the buttons with the crossponding component. For example: onclick on Add, then Add component will appears instead of the buttons.

In that case, create a boolean state for every Panel that you have (I created 3 so that you could open the panels simultaneously),

const [isAddPanelOpen, setIsAddPanelOpen] = useState(false);
const [isEditPanelOpen, setIsEditPanelOpen] = useState(false);
const [isDeletePanelOpen, setIsDeletePanelOpen] = useState(false);

Next, create an onclick function for every button

const openPanelHandler = (handler) => {
  handler();
}

Then, apply this to every button

<Button onClick={setIsAddPanelOpen(prevState=>!prevState)}>Add Notification</Button>
<Button onClick={setIsEditPanelOpen(prevState=>!prevState)}>Edit Notification</Button>
<Button onClick={setIsDeletePanelOpen(prevState=>!prevState)}>Delete Notification</Button>

Lastly, Refactor your html to

<div className="form-group">
 {isAddPanelOpen ? <AddNotification/> : <Button type="submit">Add Notification</Button>}
</div>
<div className="form-group">  
 {isEditPanelOpen ? <EditNotification/> : <Button type="submit">Edit Notification</Button>}
</div>
<div className="form-group">  
 {isDeletePanelOpen ? <DeleteNotification/> :<Button type="submit">Delete Notification</Button>}
</div>
  • Related