Skip to content

spautz/redux-to-recoil

main
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Redux-to-Recoil

Read and write your Redux store through Recoil.

npm version build status test coverage dependencies status gzip size

Usage

atomFromRedux creates a Recoil wrapper around a location in Redux. This works like any other atom.

import { selector, useRecoilState, useRecoilValue } from 'recoil';
import { atomFromRedux } from 'redux-to-recoil';

const todosAtom = atomFromRedux('.todos'); // wraps state.todos

// Inside your component, use the atoms and selectors as normal. That's it.
const [todos, setTodos] = useRecoilState(todosAtom);

// Also: it's a normal Recoil atom, so it works in Recoil selectors
const todoCountSelector = selector({
  key: 'todoCount',
  get: ({ get }) => get(todosAtom).length,
});
const todoCount = useRecoilValue(todoCountSelector);

<SyncReduxToRecoil /> syncs state from Redux to Recoil. This is required.

import { SyncReduxToRecoil } from 'redux-to-recoil';

<Provider store={store}>
  <RecoilRoot>
    <SyncReduxToRecoil />
    <MyApp />
  </RecoilRoot>
</Provider>;

selectorFromReselect creates a Recoil selector from a plain selector, using Reselect or any other selector library.

import { selectorFromReselect, useRecoilValue } from 'recoil';

const todosSelector = selectorFromReselect((state) => state.todos);

// Inside your component, use the selector as normal. That's it.
const [todos, setTodos] = useRecoilState(todosAtom);

// Also: it's a normal Recoil selector, so it works in other Recoil selectors
const todoCountSelector = selector({
  key: 'todoCount',
  get: ({ get }) => get(todosSelector).length,
});
const todoCount = useRecoilValue(todoCountSelector);

If you want to dispatch changes from Recoil back to Redux then wrap your reducer with syncChangesFromRecoil and enable the writeEnabled option. This is only needed if you set Recoil values directly.

import { syncChangesFromRecoil } from 'redux-to-recoil';

// This will enable write-from-recoil (when options.writeEnabled is turned on)
const reducer = syncChangesFromRecoil(yourRootReducer);
const store = createStore(reducer);
//  Recoil atoms and writeable selectors work like normal
const todosAtom = atomFromRedux('.todos');

const [todos, setTodos] = useRecoilState(todosAtom);

setTodos(newTodoList);

Do I need this?

You probably don't need this. Redux and Recoil work fine side-by-side. You can already use values from Redux and Recoil together in a component.

This library is useful for accessing Redux state from within a Recoil selector -- which lets you call selectors conditionally, or within loops. useSelector can't do that. (Dynamic-Selectors can, though.)

It can also facilitate a migration from Redux to Recoil.

Options

Options are available to control how and whether Recoil receives updates from, and writes updates to, Redux.

Demo

A Todo List demo shows both a read-only sync from redux and a read-write sync.

Recoil version compatibility

Recoil Redux-to-Recoil
0.7.0 0.8.x
0.6.x 0.8.x
0.5.x 0.7.1-0.8.x
0.4.x 0.6.0-0.7.1
0.3.x 0.5.1-0.6.0
0.2.x 0.4.1-0.5.1
0.1.x 0.4.1
0.0.13 0.3.1
0.0.10 0.2.2

Other versions of Recoil and Redux-to-Recoil may be compatible: this table just lists the thoroughly tested pairings.