简体   繁体   中英

Recoil: Passing a long-lived client object to a selector

Coming from react-redux / redux-thunk , there is a nice way of instantiating a client object once, passing it to ThunkMiddleware, and retrieving it in thunks:


// This is the instance I want during async calls
const myApiClient = new MyApiClient();

const store = createStore(
    reducer,
    applyMiddleware(thunk.withExtraArgument(myApiClient))
);

Then in my thunk definitions:

const fetchSomething = (id) => {
    return (dispatch, getState, myApiClient) => {
        // It's the same instance!
        return myApiClient.fetchSomething(id)
                .then((res) ....);
    }
}

In Recoil I can see no way of achieving something similar: as far as I can see, examples in the documentation assume that the body of atoms / selectors can be executed without any context instantiated externally.

Since it seems unlikely that this was not a consideration when designing Recoil, I'm curious what I've missed here?

You can use the useRecoilCallback hook, which basically offers something similar, but not as middleware. Since recoil does not have a global cohesive state in a strict sense, there is no real middleware. Think of it as a component tree like react, but for state atoms. You can connect those via selectors and query and set them via react components, but recoil itself doesn't really know about all the atoms (you can even create atoms during runtime if you want to).

So how you would go about that is something like this:

const myApiClient = new MyApiClient();

// Can also be returned by a hook.
const thunkWithExtraArgument = useRecoilCallback(({snapshot, set}) => async (myApiClient) => {
  const res = myApiClient.fetchSomething(id);

  set(atom, res.json());
}, []);

// ... Somewhere else in a component

thunkWithExtraArgument(myApiClient);

For the recoil callback hook check this out: https://recoiljs.org/docs/api-reference/core/useRecoilCallback

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