reactjsjsonrecoiljs

React JS & Recoil set/get on select/selectFamily for specific attribute


I use Recoil state management in ReactJS to preserve a keyboard letters data, for example

lettersAtom = atom(
  key: 'Letters'
  default: {
     allowed : ['A','C','D']
     pressedCounter : {'A':2, 'D':5}
  }
)

lettersPressedSelect = selector({
        key: 'LettersPressed',
        get: ({ get }) => get(lettersAtom).pressedCounter, //Not work, returns undefined
        set: () => ({ set }, pressedLetter) => {
            let newState = {...lettersAtom};
            newState.pressedCounter[pressedLetter]++;
            set(lettersAtom, newState);
        }
}),

In functional component i use

const [letters,setLetters] = useRecoilState(lettersAtom);
const [pressedCounter, setPressedCounter] = useRecoilState(lettersPressedSelect);

each time the a keyboard letter pressed the pressedCounter I want to increased for corresponded letter like that

setPressedCounter('A');
setPressedCounter('C'); ///etc...

How to achieve that ? Does recoil have a way to get/set a specific part/sub of json attribute ? (without make another atom? - I want to keep "Single source of truth") Or do you have a suggetion better best practice to do that ?


Solution

  • There are some bugs in your code: no const, braces in atom call and no get inside the set. You also need spread the pressedCounter.

    Overwise your solution works fine.

    In Recoil you update the whole atom. So in this particular case you probably don't need the selector. Here is a working example with both approaches:

    https://codesandbox.io/s/modest-wind-kosp7o?file=/src/App.js

    It a best-practice to keep atom values rather simple.