Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apps with many containers #10

Closed
djMax opened this issue May 8, 2019 · 12 comments
Closed

Apps with many containers #10

djMax opened this issue May 8, 2019 · 12 comments

Comments

@djMax
Copy link

djMax commented May 8, 2019

I'm trying to get my head around the new approach and there are a few things I'm getting stuck on. Part 1 - if I have 10 containers (as I do in my unstated implementation), do I now have to list every one of them at the top level? I certainly appreciated just being able to wrap my App component in <Provider><App /></Provider> and be done with it.

@jamiebuilds
Copy link
Owner

Yeah, that's something I would like to figure out.

import { compose } from "unstated-next"

let Provider = compose(ContainerOne, ContainerTwo)

However unless React adds an API for useProvider or something there's always going to be a bunch of nodes in the React tree.

I'd also like to experiment with "auto-registering" to make code splitting easier.

@djMax
Copy link
Author

djMax commented May 8, 2019

In the regular unstated world, how did it get around this issue?

@neves
Copy link

neves commented May 8, 2019

Is there something like:

<Subscribe to={[AppContainer, CounterContainer, ...]}>
  {(app, counter, ...) => (
    <Child />
  )}
</Subscribe>

@djMax
Copy link
Author

djMax commented May 8, 2019

I'm using something like this now, that seems to be working:

import React from 'react';

export interface ContainerProviderProps {
  children: React.ReactNode
}

export interface Container {
  state: Map<String, any>;
}

export function ProviderFactory() {
  const Context = React.createContext(null);
  const containerMap = new Map();

  return {
    Provider({ children }: ContainerProviderProps) {
      return <Context.Provider value={containerMap}>{children}</Context.Provider>;
    },
    useContainer(ContainerClass) {
      const value = React.useContext(Context);
      if (value === null) {
        throw new Error('Component must be wrapped with <Provider>');
      }
      const containerInstance = value[ContainerClass];
      if (!containerInstance) {
        const newContainer = new ContainerClass();
        containerMap[ContainerClass] = newContainer;
        return newContainer;
      }
      return containerInstance;
    },
  };
}

const sharedFactory = new ProviderFactory();

export const { useContainer, Provider } = sharedFactory;

@jamiebuilds
Copy link
Owner

@neves

let app = AppContainer.useContainer()
let counter = CounterContainer.userContainer()
<Child />

@djMax
Copy link
Author

djMax commented May 8, 2019

My hack didn't really work. Instead I modified unstated to use a common Map() instead of per-Provider instance.

@Lenic

This comment has been minimized.

@jamiebuilds
Copy link
Owner

I think I'm going to avoid adding something like this for now. I've written at length about why here: #20 (comment)

@neckaros
Copy link

neckaros commented Jun 9, 2019

What is the recommanded way to do as the issue state "Apps with many containers" ?
Compose seems to have been removed.

@Flcwl
Copy link

Flcwl commented Jan 27, 2020

Not maintained?

@csr632
Copy link

csr632 commented Apr 1, 2020

You can checkout my idea: react-hook-svs. Highlights:

  • Get service output immediately in the hosting component. You no longer need to wrap your top component with provider HOC to get service output in it.
  • One service can consume another, even when they are in the same component. react-hook-svs provides a consistent way to consume service.
  • Service providers(basically React context) are composited together and will be injected into a JSX subtree at once. No longer provider hell. Checkout this demo:

Edit react-hook-svs

@hck1205
Copy link

hck1205 commented May 18, 2020

Yeah, that's something I would like to figure out.

import { compose } from "unstated-next"

let Provider = compose(ContainerOne, ContainerTwo)

However unless React adds an API for useProvider or something there's always going to be a bunch of nodes in the React tree.

I'd also like to experiment with "auto-registering" to make code splitting easier.

Yeah, that's something I would like to figure out.

import { compose } from "unstated-next"

let Provider = compose(ContainerOne, ContainerTwo)

However unless React adds an API for useProvider or something there's always going to be a bunch of nodes in the React tree.

I'd also like to experiment with "auto-registering" to make code splitting easier.

Hello, I am working on project with unstated
and not so sure if what I am working on would be anti pattern
I am using unstated like below

class ContainerA extends Container {}
const containerA = new ContainerA();
export default containerA;

class ContainerB extends Container {}
const containerB = new Containerb();
export default containerB;

const rootStore = [ContainerA, ContainerB]

  <Provider>
     <Subscribe to={rootStore}>
       <App />
     </Subscribe>
  </Provider>

components where needs to access to stores

import {ContainerA} from 'stores'

const {some, properties, ... } = ContainerA.state

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants