I have tested two ways to switch between screens for simple application (Max 3 modes/screens). Still learning the ropes and focusing on practicing with useState and maybe useEffect for some cases.
Would like to know if there are other ways (without using routers) for switching between modes/screens.
Practice Run #1:
Objective, create a common Modal component so I can keep screen design in one high level component. This modal contains a close button, and renders provided children. Data context stays with parent. The Add and Edit events have their own states. At the moment, I don’t care to keep data if someone closes and opens the model again.
Cons: I feel there are too many isShow?? tests in this method. Ideally, all state can go with parent. If this goes above 3x modes/screens – it would get a bit clunky with switch statement.
// Simple modal with isShown, close button and children
const Modal = ({ isShown, onClose, children }) => {
return (
<>
{isShown && (
<div className='modal-overlay'>
<div className='modal'>
{children}
<button onClick={onClose}>X</button>
</div>
</div>
)}
</>
)
}
// Simple add event comp, takes onSubmit callback to send data to parent
const AddEvent = ({ onSubmit }) => {
const [name, setName] = useState('')
console.log('Render Add Event')
return (
<>
<div>
<p>Add Event Mode:</p>
<input
type='text'
name='name'
placeholder='set your name'
onChange={(e) => setName(e.target.value)}
value={name}
/>
<button id='some' onClick={() => onSubmit(name)}>
Send Name to Parent
</button>
</div>
</>
)
}
// Simple edit event comp, takes originalData from parent and onSubmit callback to send modified data to parent
const EditEvent = ({ originalData, onSubmit }) => {
const [name, setName] = useState(originalData)
console.log('Render Edit Event')
return (
<>
<div>
<p>Edit Event Mode:</p>
<input
type='text'
name='name'
placeholder='set your name'
onChange={(e) => setName(e.target.value)}
value={name}
/>
<button id='some' onClick={() => onSubmit(name)}>
Send Data to Parent
</button>
</div>
</>
)
}
// The main app comp. state for modal, data and step (add, edit).
export default function App() {
const [showModal, toggleShowModal] = useState(false)
const [parentData, setparentData] = useState('')
const [step, setStep] = useState({ add: false, edit: false })
// Main function to toggle event mode.
const toogleEventMode = (e) => {
console.log('Switching modes')
switch (e.target.name) {
case 'add':
setStep({ add: true, edit: false })
toggleShowModal(true)
break
case 'edit':
setStep({ add: false, edit: true })
toggleShowModal(true)
break
}
}
return (
<>
<h3>Click on Add Event to add an event, and then Edit</h3>
<Modal isShown={showModal} onClose={() => toggleShowModal(false)}>
{step.add && (
<AddEvent
onSubmit={(dataFromAddEvent) => setparentData(dataFromAddEvent)}
/>
)}
{step.edit && (
<EditEvent
onSubmit={(dataFromEditEvent) => setparentData(dataFromEditEvent)}
originalData={parentData}
/>
)}
</Modal>
<div className='card'>
<button name='add' onClick={(e) => toogleEventMode(e)}>
Add Event
</button>
<button name='edit' onClick={(e) => toogleEventMode(e)}>
Edit Event
</button>
</div>
</>
)
}
2
Answers
The second method is much simpler, but useful for three action sections. Add, Edit and Delete. The example I worked on is only for Add/Edit.
Here I can add a Layout component, that returns children. Used purely for styling.
The following shows how to use useReducer – albeit a bit clunky for now. Will polish this as use case is defined further.
END of this Q&A post.