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

Q: How to trigger store action from outside component? #139

Open
kwiniarski97 opened this issue Jul 14, 2021 · 4 comments
Open

Q: How to trigger store action from outside component? #139

kwiniarski97 opened this issue Jul 14, 2021 · 4 comments
Labels
question Further information is requested

Comments

@kwiniarski97
Copy link

kwiniarski97 commented Jul 14, 2021

I have some axios interceptor written that in some circumstances should dispatch an action from core store.
I tried exporting a store object and importing it into the file, but that does not call the inner function.
How can you achieve this behaviour?

I've made a simple reproduction, what is not working. https://codesandbox.io/s/cool-pine-pwepc?file=/src/App.js
When clicking on the "normal on click" the counter is incremented. I don't know however how can I make it work the same way for "outside fn click"

@ninjz
Copy link

ninjz commented Jul 15, 2021

For each of my stores I like to export a StoreInstance using defaultRegistry like so:

// store.ts
import { defaultRegistry, createStore } from 'react-sweet-state'

const Store = createStore({
  name: 'defaultStore',
  initialState,
  actions,
})

export default defaultRegistry.getStore(Store)

Now I can just import this file and have reference directly to the StoreInstance which allows me to perform and actions and access its state outside of a component.

import Store from './store'

// Perform action
Store.actions.doThis()

// Retrieve state
Store.storeState.getState().someState

@kwiniarski97
Copy link
Author

I tried it and it works :) Thank you, @ninjz.

Is this part of the documentation?

@ninjz
Copy link

ninjz commented Jul 18, 2021

Doesn't look like it. Seems like it would be a great addition to it though.

I only found out about defaultRegistry through digging into the code a while back. I've always felt the need to have access to the stores outside the component so it really felt limiting when this wasn't presented as a feature.

cc: @albertogasparin

@albertogasparin albertogasparin added the question Further information is requested label Aug 1, 2021
@albertogasparin
Copy link
Collaborator

albertogasparin commented Aug 1, 2021

The reason why that is not documented (or typed) and is still a private API is because works only for global stores and does not handle Container props. As soon as you add a Container those expectations break and we either get a different instance or the actions might not receive the expected arguments.
So I would suggest grabbing the value from the render tree as a more solid way (even if a bit more verbose) to ensure the store you retrieve is actually the one gives data to your components.
It can be done by adding a hook that exposes state/actions to a module level variable:

// store.ts
import { createStore, createHook } from 'react-sweet-state'

const Store = createStore({
  name: 'defaultStore',
  initialState,
  actions,
});

const instance = { state: null, actions: null };

const useStore = createHook(Store);

const useStoreReference = () => {
  const [state, actions] = useStore();
  instance.state = state;
  instance.actions = actions;
  return null;
}

export default instance;

Now rendering useStoreReference will provide the accurate instance.

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