teafuljs/teaful

Add value field to Provider for reusability.

Lunuy opened this issue · 4 comments

Lunuy commented

What version of this package are you using?
0.2.1

What problem do you want to solve?
Default value of store is fixed so store's reusability is not good.

What do you think is the correct solution to this problem?
Add value option to Provider props. It will looks like original Context API's Provider.
It makes breaking change (because value field of Provider is required field), so I want to know how do you think about it.

Are you willing to submit a pull request to implement this change?
After maintainer's feedback, yes.

Example

import createStore from "fragmented-store";

const { Provider, useUsername, useAge, useStore } = createStore({
  username: "Aral",
  age: 31
}); // It is just default values that used when hook can't find appropriate Provider.

export default function App() {
  return (
    <Provider value={{
        username: "Aral",
        age: 31
    }}>
      <Title />
      <UpdateTitle />
      <Age />
      <AllStore />
    </Provider>
  );
}

I agree! I like the idea

@Lunuy I implemented callbacks as a second param of createStore:

Do you think it would also be interesting to switch to the provider? I think so, if you look at the example instead of an alert it can be used a dialog or rendered component. What do you think?

Lunuy commented

Yes, I think callbacks should in Provider's props instead of createStore's argument. Because user may want to use another Context / state in callback. If user wants separate callback definition and Provider usage code, user may make own Provider.

const defaultStore = {
  quantity: 2,
  userName: 'Aral',
  age: 31,
}

const { Provider, useQuantity } = createStore(defaultStore);

// Make own provider.
export const MyContextProvider = ({ store, children }) => {
    const apolloClient = useApolloClient();
    
    const callbacks = {
      quantity: (newValue, prevValue, setValue) => {
        // Update quantity on API
        apolloClient.mutate(...)
         // Revert state change if it fails
         .catch(e => setValue(prevValue))
      },
      age: (newValue, prevValue, setValue) => {
        if (newValue > 100) {
          alert("Sorry, no more than 100 😜");
          setValue(prevValue);
        }
      }
    }
    
    return (
        <Provider store={store} callbacks={callbacks}>
            {children}
        </Provider>
    );
};

#4

Done on fragstore 0.4.0 (fragmented-store is renamed to fragstore)