renatorib / react-powerplug

:electric_plug: Renderless Containers
https://renatorib.github.io/react-powerplug
MIT License
2.68k stars 101 forks source link

RFC: ElementContainer #171

Closed slorber closed 5 years ago

slorber commented 6 years ago

I often use this trick in my app, mostly for modals that are stateful/connected. I'm thinking publishing it but it could also be a good fit for this project so here I am...

const App = () => (
  <ElementContainer>
    {({ add }) => (
      <div onClick={() => add(remove => <MyModal onClose={() => remove()} />)}>
        show modal
      </div>
    )}
  </ElementContainer>
);

The idea is that it should not be painful to add / remove a portal to your tree and forcing you to migrate to stateful components.

pros

cons


An alternative could be to write:

const App = () => (
  <Toggle>
    {({ on, set }) => (
      <React.Fragment>
        <div onClick={() => set(true) />)}>
          show modal
        </div>
        {on && <MyModal onClose={() => set(false)} />
      </React.Fragment>
    )}
  </ElementContainer>
);

pros

cons


I already have a working implementation for this, just want to know if you would accept it in the project and if so discuss about api details

slorber commented 6 years ago

Let's also consider the case where I have something

const App = () => (
  <ElementContainer>
    {({ add }) => (
      <UserList
        onUserSelected={userId =>
          add(remove => <UserModal userId={userId} onClose={() => remove()} />)
        }
      />
  </ElementContainer>
);

If I were to open the modal with other comps it would be:

const App = () => (
  <Value>
    {({ value, set }) => (
      <React.Fragment>
        <UserList onUserSelected={userId => set(userId)}/>
        {value && <UserModal userId={value} onClose={() => set(undefined)} />
      </React.Fragment>
    )}
  </ElementContainer>
);

The Value-based code is less clear to me (and does not support multiple modals at once), particularly for cases where the initial props we want to inject in the modal is provided in the callback, it forces us to store that value somewhere first before rendering the modal

renatorib commented 5 years ago

I think it is much specific. Powerplug must have generic utilities. I can not see many usecases for this component. I think the example using Value is super simple, I have not seen problems with it.

slorber commented 5 years ago

ok fine I'll implement something myself, probably will try with hooks