简体   繁体   中英

React Native: HeadslessJS and Redux - How to access store from task

We have a ReactNative app that uses redux, redux-persist and a HeadlessJS task. This task needs to have access to the store. As the task fires without booting the entire app (and so has no access by default), we thought we could simply create the store inside the task as well so that it would be rehydrated by redux-persist. It turns out, however, that the store created in this way is different from the one in the app: after running, they contain different values. We tested this in several ways and it seems indeed a problem with the stores (and not with the actions for instance) How should we access a Redux store from an HeadlessJS task?

Relevant code: store/configure.js :

configureStore = (client) => {
  const middleware = createMiddleware(client);
  const finalCreateStore = applyMiddleware(thunk, middleware, logger)(createStore);
  const store = finalCreateStore(rootReducer, undefined, autoRehydrate());

  return store;
};

In use (both in the app and in the service):

const client = new ApiClient();
const store = configureStore(client);
client.setStore(store);
persistStore(store, {
  storage: AsyncStorage,
}

In the app we simply use the Provider from react-redux to use the store, in the service we use store.dispatch.

simply create the store inside the task as well so that it would be rehydrated by redux-persist.

This did indeed happen.

You created two stores (not advisable with redux) which were both hydrate, but not linked, as there is no such thing as linked redux stores. Every time you run createStore, it's a new store. And every time you dispatch, you do that on a specific store.

Unfortunately async or multithreaded issues are not directly addressed by redux.

It would be possible though with middleware and / or store listeners to keep the two stores in sync.

But redux is also just not a mean for communication between threads (which I assume these tasks are, or you could just give the task a reference to the store once it was created or give the main app the store reference from the task).

It's more a form of Command-Query-Separation and centralized state.

For people looking for solution. I have found the solution in here. The idea is to bind the store to async method.

https://github.com/react-native-kit/react-native-track-player/issues/63

Copy pasting the solution here.

// index
const store = ...
....registerHeadlessTask('TrackPlayer', () => require('event-handler.js').bind(null, store));
// event-handler.js
module.exports = async (store, data) {
    if(data.type == '...') {
        store.dispatch(...);
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM