GithubHelp home page GithubHelp logo

Comments (10)

drarmstr avatar drarmstr commented on May 8, 2024 10

There is a useTransactionObservation_UNSTABLE hook you can use to subscribe to state changes for managing persistence. There is also a persistence_UNSTABLE option for atoms to add metadata, such as a validator function. It's listed as _UNSTABLE as we're still finalizing the API, but we use this internally. We're working now to clean up this API and publish an example persistence library.

from recoil.

drarmstr avatar drarmstr commented on May 8, 2024 5

@Qrysto @Joonpark13 - Yup, stay tuned for "Atom Effects" coming soon...

from recoil.

DynamicArray avatar DynamicArray commented on May 8, 2024 1

FWIW, I like the idea.

Recoil has allowed me to break down my state to neat, reusable parts. In a complex application, that's a real plus and the code is much cleaner than redux/context versions I've had before.

But there are plenty of occasions where the state logic (separate from the display logic) demands knock-on effects and it feels right to try to wrap those parts of the code in together.

from recoil.

Shmew avatar Shmew commented on May 8, 2024 1

I think a great way to handle it would be to have a type like EffectSubscriber<T> where you would dispatch messages of type T to it and it has the ability to parse the sent data and set atoms and perform effects as needed. It would let the subscriber be ignorant of how it gets messages which means it could even be sent new data from multiple sources (and be less fragile to code changes).

In addition, it would be awesome to have its own state as well. This would really enable a MVU pattern within recoil. So it would be something along the lines of giving it an initial state and like the set field for selectors where it takes the object to perform operations {set: SetRecoilState, get: GetRecoilValue, reset: ResetRecoilState} and the new message T and then returns the new state and any effects to dispatch (like an array of void => void).

Where it would look something like this:

const mySubscriber = effectAtom({
    key: 'mySubscriber',
    default: { someField: 1 },
    update: ({get, set}, msg, state) => {
        if (msg.tag == SomeType.SomeMsg) {
            return { someField: msg.value + state.someField }, []
        }
        else {
            return state, [() => console.log("hello!")]
        }
    }
});

Ideally modifying the state would be done inside the effect array as well to make the update function pure(er), but in either case I think this would be effective.

This is a well established pattern in Elm, F#, and other functional languages as a way for handling effects.

I don't know, but this idea of making the effects lazy might help with concurrent mode compatibility?

from recoil.

davidmccabe avatar davidmccabe commented on May 8, 2024

As Douglas said we have an API that you can use for this currently, albeit it's a bit half-baked and we're planning a much better and more flexible version soon. In the meantime, check out useTransactionObservation and the initializeState prop of RecoilRoot (unlike what you have with default there this doesn't depend on module evaluation timing.)

If you just want an effect to be triggered by changes to a specific atom, you can also have a component with useEffect.

from recoil.

Qrysto avatar Qrysto commented on May 8, 2024

I think there still needs to be a way to subscribe to individual atoms instead of relying on only useTransactionObservation_UNSTABLE, since one of the main points of using recoil instead of redux is to avoid triggering ALL unrelated subscribers at every single change in the app state.

from recoil.

DynamicArray avatar DynamicArray commented on May 8, 2024

Having looked at the new "Atom Effects", there still doesn't seem to be a simple way to alter the value of one atom when another's state changes. Perhaps you envisage selectors for that, but I've yet to see (or figure out) a way to make that work neatly if both states are atoms.

"Atom Effects" has setSelf/resetSelf, but what if I want to setOther/resetOther?

Is there/will there be a way to subscribe to one atom and then set another on change, without going the useEffect route (which just feels clunky)?

This my current approach, but I dislike the way it's separate from my main state code.

DimensionsAtom needs to be reset whenever listingAtom changes.

function StateManager() {
    const listing = useRecoilValue(listingAtom);
    const setDimensions = useSetRecoilState(dimensionsAtom);

    useEffect(() => {
        setDimensions({});
    }, [listing]);

    return null;
}

from recoil.

drarmstr avatar drarmstr commented on May 8, 2024

Contemplating adding some sort of onListen() for an atom effect to listen to other atoms/selectors. But, trying to reason if it's really justified and doesn't encourage bad patterns.

from recoil.

devarsh avatar devarsh commented on May 8, 2024

Currently, this is how I have implemented a watcher facility for my form.

export const subscribeToFormFieldsSelector = selectorFamily<
  FormFieldAtomType[],
  string[] | undefined
>({
  key: atomKeys.subscribeToFormFieldsSelector,
  get: (fields = []) => ({ get }) => {
    if (!Array.isArray(fields)) {
      fields = [fields];
    }
    let fieldValues: FormFieldAtomType[] = [];
    for (let field of fields) {
      if (typeof field === "string" && field !== "") {
        let fieldState = get(formFieldAtom(field));
        fieldValues.push(fieldState);
      }
    }
    return fieldValues;
  },
});

from recoil.

drarmstr avatar drarmstr commented on May 8, 2024

Covered by atom effects

from recoil.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.