0

In some components i am using recoil atoms to manage my states. One example is my modal component. It look something like this:

export const modalState = atom({
  key: "modalState",
  default: false
})

export const useToggleModalState = () => {
  const setModalState = useSetRecoilState(modalState)
  return (state, callback) => {
     setModalState(state)
     if (callback) {
        callback()
     }
  }
}

export const Modal = (props) => {
  <Transition show={modalState}>
    <Dialog>
      <Dialog.Title>My Modal Headline</Dialog.title>
      <Dialog.Description>My Modal Description</Dialog.Description>
    </Dialog>
  </Transition>
}

and i am using this modal like this:

const toggleModalState = useToggleModalState();

return (
  <Modal />
  <Button text="Close Modal" onClick={() => toggleModalState(false)} />
)

however, if I use the modal multiple times, the modal is automatically duplicated, but I still use only one state for all modals. Of course, I don't want that. If I use a component multiple times, I want the state to be created multiple times, so that I can change the state of each component individually.

I have read that there are also atomFamilys. Could I use these at this point? What should my code look like then? Can multiple atoms also be created automatically if I use a component multiple times?

Niklas
  • 1,638
  • 4
  • 19
  • 48

1 Answers1

0

Why do you want to use recoil for that? The state of the modal is tied to the modal itself, it doesn't need to access global state.

You can just use useState to determine if you want to show a modal within a component:

export const Modal = (props) => {
  <Transition show={props.show}>
    <Dialog>
      <Dialog.Title>My Modal Headline</Dialog.title>
      <Dialog.Description>My Modal Description</Dialog.Description>
    </Dialog>
  </Transition>
}

export const ComponentWithModal = () => {
  const [showModal, setShowModal] = useState(false);

  return (
    <>
      <Modal show={showModal}/>
      <Button text="Open Modal" onClick={() => setShowModal(true)} />
      <Button text="Close Modal" onClick={() => setShowModal(false)} />
    </>
  )
}
Johannes Klauß
  • 10,676
  • 16
  • 68
  • 122
  • I agree, `useState` can definitely be used as well. However, I would like to make my state management a bit simpler and more centralized. I also used your approach at first, but with time it just gets confusing. Which components are stateless or stateful? Another possibility would be to define the states for example in the modal itself, but again you have to work with ref etc. to be able to change the state outside. I have already found a solution. With `atomFamily` it works now. Thanks anyway – Niklas May 06 '21 at 15:08