Light and simple React global state management.
Latest docs here
To create a store
const initialState = { todos: ['Task 1', 'Task 2'] }
export const TodosLightState = new LightState(initialState)
// => store: {todos: ["Task 1", "Task 2"]}
Get this store
// with React Hooks
const { useStore } = TodosLightState
function Listing() {
const todos = useStore(state => ({ todos: state.todos }));
return (
<Wrapper>
<List todos={todos} />
</Wrapper>
)
}
// or directly get from Store
TodosLightState.getState()
// or
const { getState } = TodosLilghtState
getState()
// => {todos: ["Task 1", "Task 2"]}
Update this store
// directly
const {setState} = TodosLightState;
setState({
todos: [...TodosLightState.getStore().todos, 'Task 3']
})
// => {todos: ["Task 1", "Task 2", "Task 3"]}
// async update
setState(async currentState => {
let data = await fetchData();
return { todos: currentState.todos.concat(data) }
})
// callback
setState({...someData}, (newState) => {
...
})
or dispatch
const {dispatch} = TodosLightState;
dispatch((dispatch, currentState) => {
dispatch({loading: true});
fetchData().then(data => {
dispatch({loading: false, data: data})
})
}, newState => {
...
})
Use with React. Connect your react component with withLight
or connect
export default TodosLightState.withLight()(MappedComponent)
// or
export default TodosLightState.connect()(MappedComponent)
/**
* your component will map state of LightState to your props,
* the default props will be `yourOptionalStoreName`, if the LightState doesn't
* have default store name the props will be `lightProps`
* /
So your mapped component look like
const MappedComponent = ({ yourOptionalStoreName, ...yourRestProps }) => {
return (
<ul>
{yourOptionalStoreName.todos.map((todo, idx) => (
<li key={idx}>{todo}</li>
))}
</ul>
)
}
The Light State can save to localStorage by default
new LightState(initialState, 'yourOptionalStoreName', {
storageName: 'YourTodosStorageName', // [REQUIRED] if you want to save the data.
getFromStorage: () => {}, // [OPTIONAL] custom function get data
saveToStorage: () => {} // [OPTIONAL] custom function save data
})
npm install react-light-state
# or
yarn add react-light-state
# or
npm install @fozg/react-light-state
Setup Light State:
import LightState from "react-light-state";
export const TodosLightState = new LightState({list: ["Task 1", "Task 2"]}, "todos");
/**
* `todos` is store name, when you connect the LightState with your component
* with api withLight(), your store name will be default props.
*
* If store name is null, default props will be `lightProps`.
*
* Otherwise, you can define function `mapStateToProps` at withLight(mapStateToProps)
* to specify which field you want to use..
* /
Use with your component:
import { TodosLightState } from '../setupLightState'
const ViewTodos = ({ todos }) => (
<div>
<ul>
{todos.list.map((todo, idx) => (
<li key={idx}>{todo}</li>
))}
</ul>
</div>
)
export default TodosLightState.withLight()(ViewTodos)
Update TodoLight:
import { TodosLightState } from '../setupLightState'
const { setState, getState } = TodosLightState
function AddTodo(todos) {
const [todo, setTodo] = useState('')
return (
<div>
<input
placeHolder="Enter todo"
value={todo}
onInput={e => {
setTodo(e.target.value)
}}
/>
<button
onClick={() => {
setState(...getState().list, todo)
}}
/>
</div>
)
}
import React, { useState } from 'react'
import LightState from 'react-light-state'
const TodoStore = new LightState(['My frist todo'], 'todos')
const TodoApp = TodoStore.withLight()(({ todos }) => {
const [input, setInput] = useState('')
return (
<div>
Todo list:
{todos.length === 0 && 'No todo found'}
<ul>
{todos.map((todo, idx) => (
<li key={idx}>{todo}</li>
))}
</ul>
Enter todo:
<form
onSubmit={e => {
e.preventDefault()
TodoStore.setState([...todos, input])
setInput('')
}}
>
<input
value={input}
onChange={e => {
setInput(e.target.value)
}}
/>
<input type="submit" value="Add" />
</form>
</div>
)
})
export default TodoApp
import {Light} from TodosLightState;
// your component
() => (
<Light mapStateToProps={state => ({todos: state.todos})}>
{({todos}) => (
<div>
{todos.map(item => ...)}
</div>
)}
</Light>
)