Toolkit for React Context API heavily inspired by @reduxjs/toolkit and react-redux
npm install react-context-toolkitToolkit for React Context API - heavily inspired by @reduxjs/toolkit and react-redux. Written in TypeScript.
- It uses the React Context API instead of Redux for managing state under the hood.
- Depends on use-context-selector to prevent unneccesary rerenders. (https://github.com/reactjs/rfcs/pull/119)
I really like the combination of react-redux and @reduxjs/toolkit. React-Redux won't work for me due to this issue:
- https://github.com/visgl/deck.gl/issues/4550
The context API in React doesn't suffer from the same problem, so I decided to make this feel more like I'm using Redux.
``js`
const {
StateProvider,
useSelector,
useDispatch,
Store,
initialState,
rootReducer,
} = createStore([
slice1,
slice2,
// ...
])
| returned object | description |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| StateProvider | The context provider (React Element) that provides the store to all its children |useSelector(selector)
| | Hook that selects from the global store (and only rerenders if the selected state has changed) |useDispatch()
| | Hook that returns a dispatch function, just like the one in React-Redux |Store
| | In case you need direct access to the React Context object |initialState
| | The complete initial state. The slice names are keys, under which each slice has its own initialState |rootReducer(state, action)
| | The reducer that takes in the combined state, an action, and produces a new combined state |
`shUsing npm
npm install --save react-context-toolkit
Example
Also, check out the test folder for another example.
$3
`tsx
// ./src/index.tsximport React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { StateProvider } from './app/store'
// Wrap your app in the state provider like this:
ReactDOM.render(
,
document.getElementById('root')
)
`$3
Notice that it doesn't need to know anything about the store
`tsx
// src/App.tsximport React from 'react'
import Component1 from '../features/component1/Component1'
import Component2 from '../features/component2/Component2'
import Component3 from '../features/component3/Component3'
// Note that the App component doesn't need to know anything about the store!
export default function App () {
return (
<>
>
)
}
`$3
`ts
// src/app/store.tsimport { createStore } from 'react-context-toolkit'
import componentSlice1 from '../features/component1/componentSlice1'
import componentSlice2 from '../features/component2/componentSlice2'
import componentSlice3 from '../features/component3/componentSlice3'
export const {
useSelector,
useDispatch,
StateProvider,
initialState,
} = createStore([componentSlice1, componentSlice2, componentSlice3])
// In case you need direct access to the type of the combined state
export type RootState = typeof initialState
`$3
`ts
// src/features/component1/componentSlice1.tsimport { createSlice, PayloadAction } from 'react-context-toolkit'
// ^ You can also import these from '@reduxjs/toolkit'
import { RootState } from '../../app/store'
const slice = createSlice({
// This name becomes the key in the global state
name: 'component1',
initialState: {
value: 1,
},
reducers: {
// uses immer reducers to allow mutations on an intermediate draft state
increment (state) {
state.value++
},
incrementBy (state, action: PayloadAction) {
state.value += action.payload
},
},
})
export const { increment, incrementBy } = slice.actions
export const selectValue = (state: RootState) => state[slice.name].value
`$3
`tsx
// src/features/component1/Component1.tsximport React from 'react'
import { useSelector, useDispatch } from '../../app/store'
import { increment, incrementBy, selectValue } from './componentSlice1'
export default function Component1 () {
const value = useSelector(selectValue)
const dispatch = useDispatch()
return (
)
}
``- Ability to add your own middleware/docs
- Redux-thunk support/docs
- Redux-saga support/docs
- Persistence support/docs (using localStorage) -> requiring serializable state
- Reselect support/docs (for computationally intensive selects)