umi-plugin-recoil
A plugin for [email protected] to help you set RecoilRoot.
What is Recoil?
Recoil provides a fast and flexible way to share state across components with React Hooks Api.
What does this plugin do?
- Inject
RecoilRootto umi root container. So you can useuseRecoilStatein your code without declaring aRecoilRootcontext. - Provide an
useRecoilObjStateApi which can shallow merge your object-type state when callingsetState. - list-type state operator
- history-travel state operator
-
RecoilRootoptions
How to use?
Install dependencies with npm or yarn in you umijs@3 project
npm install umi-plugin-recoil
# or
yarn add umi-plugin-recoil
Create Recoil Atom in the right place
I am used to place the Atom inside ‘recoil’ folder like this.
Create Atom
Use atom to create a store that can be shared across your project.
import { atom } from 'recoil';
const myState = atom({
key: 'myState',
default: 'val',
});
export default myState;
You can also create an object-type Atom.
import { atom } from 'recoil';
const myObjState = atom({
key: 'myObjState',
default: {
name: 'this is an object',
value: 123,
},
});
export default myState;
Use state in your code
Use useRecoilState like useState to implicitly subscribe the component to the given state.
import React from 'react';
import { useRecoilState } from 'recoil';
import myState from '@/recoil/myState';
export default () => {
const [state, setState] = useRecoilState(myState);
return (
<div>
<div>{state}</div>
<button
onClick={() => {
setState('clicked');
}}
>
Click
</button>
</div>
);
};
[Special] Merge object-type state when setState
This plugin provides an useRecoilObjState Api which allow you subscribe an object-type atom and shallow merge the object when calling setState.
You should import the useRecoilObjState Api from umi;
import React from 'react';
import { useRecoilObjState } from 'umi'; // import from umi
import myObjState from '@/recoil/myObjState'; // see above
export default () => {
const [objState, setObjState] = useRecoilObjState(myObjState);
return (
<div>
<div>{objState.name}</div>
<div>{objState.value}</div>
<button
onClick={() => {
// objState will change to { name: 'this is an object', value: 888 } ;
setObjState({
value: 888,
});
}}
>
Click
</button>
</div>
);
};
