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

Possible to update provider state with other Factory #2

Closed
sammdec opened this issue May 30, 2018 · 6 comments
Closed

Possible to update provider state with other Factory #2

sammdec opened this issue May 30, 2018 · 6 comments
Labels
question Further information is requested

Comments

@sammdec
Copy link

sammdec commented May 30, 2018

Love this project but had a question around being able to update the provider store with one of the factory functions provided. I know this would replicate some of how redux works but it would be nice if there was a way to do it with the built in factory functions almost like a withProviderHandlers.

@fahad19
Copy link
Owner

fahad19 commented May 30, 2018

Hi @samjbmason! Thanks for the kind words :D

Providers are actually meant to be accessed as references only. We do not add, remove or replace them from factories.

So let's say if you have a Redux store set in your providers under the store key:

const myProviders = {
   store: reduxStore
};

From any other factory functions, we can access this store, and also call it's methods, which may result in changing its own state. But we don't replace the store itself with some other value.

You can still do this:

import { compose, withProps } from 'proppy';

const P = compose(
  withProps((props, providers) => {
    return {
      foo: 'foo value',
      dispatchIncrement: () => store.dispatch({ type: 'INCREMENT' })
    };
  })
);

const p = P(myProviders);
p.props.dispatchIncrement();

I would be curious to know more about your use cases though :)

@sammdec
Copy link
Author

sammdec commented May 31, 2018

Hey @fahad19 thanks for getting back so quickly.
I guess my use case is kind of similar to the redux example, Im using unistore in a big project and it felt like some kind of inbuilt way of updating the provider would essentially mean I could go from 2 libraries (currently recompose and unistore) to just proppy

@fahad19
Copy link
Owner

fahad19 commented May 31, 2018

@samjbmason: I think I understand what you mean now.

You want to:

  • Create a Store with ProppyJS, and
  • Set that Store as a Provider
  • Use ProppyJS with the Components layer as normal

Basically ProppyJS for ALL the things 😱


Let's see what we can do:

Create a Store

Similar to Redux API:

import { withReducer } from 'proppy';

function reducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { value: state.value + 1 };
    case 'DECREMENT':
      return { value: state.value - 1 };
    default:
      return state;
  }
}

const initialState = { value: 0 };

const S = withReducer('counter', 'dispatch', reducer, initialState);

const s = S();

// Redux API-like store
const store = {
  getState() { return s.props.counter },
  dispatch(action) { return s.props.dispatch(action); },
  subscribe(cb) { return s.subscribe(props => cb(store.getState()); }
};

Set it as a Provider

import { ProppyProvider } from 'proppy-react';

const myProviders = {
  store: store,
};

function Root() {
  return (
    <ProppyProvider providers={myProviders}>
     <OtherComponent />
   </ProppyProvider>
  );
}

Access it from anywhere in components tree

import { compose, shouldUpdate } from 'proppy';
import { withStore } from 'proppy-redux'; // doesn't require Redux
import { attach } from 'proppy-react';

const actions = {
  increment: () => ({ type: 'INCREMENT' })
};

const P = compose(
  withStore(
    // mapState
    state => ({ counter: state.value }),

    // mapDispatch
    actions
  ),
  shouldUpdate((prevProps, nextProps) => true)
);

function MyComponent(props) {
  return <p></p>;
}

export default attach(P)(MyComponent);

@sammdec
Copy link
Author

sammdec commented May 31, 2018

Ha ha yeah thats the dream ProppyJS for everything! We arent actually using redux we are in fact using unistore which has a much simpler API. Would it be possible to do something similar to the above without the redux focus?

Also thanks for taking the time with this, I understand you must be busy

@fahad19 fahad19 added the question Further information is requested label Jun 13, 2018
@chimon2000
Copy link
Contributor

@samjbmason as a workaround, I created another context and pass it props defined in my app component

const P = compose(
    withStateHandlers(
        { isLoggedIn: isLoggedIn() },
        {
            setLoggedIn: isLoggedIn => () => {
                return { isLoggedIn }
            }
        }
    )
)

const App = ({ isLoggedIn, setLoggedIn }) => (
    <React.Fragment>
        <AppContext.Provider value={{ isLoggedIn, setLoggedIn }}>
            {isLoggedIn && <Header />}
            <Routes isLoggedIn={isLoggedIn} />
        </AppContext.Provider>
    </React.Fragment>
)

It's not as elegant as your example of having a unistore-like api built into proppy, but it is still less boilerplate than the redux version. A unistore-esque api seems like a good candidate for a plugin @fahad19

@fahad19
Copy link
Owner

fahad19 commented Sep 24, 2018

@chimon2000, @samjbmason: I would really welcome some spec/proposal for a new package for this.

We also have https://github.com/proppyjs organization. can use that for more repos :)

@fahad19 fahad19 closed this as completed Sep 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants