🚀 Add doc of APIs
This commit is contained in:
parent
1088b8ea80
commit
31f8b4c438
|
@ -0,0 +1,255 @@
|
|||
# NodeRedux Module
|
||||
Redux is a predictable state container for lua apps and NodeMCU.
|
||||
|
||||
## Influences
|
||||
|
||||
NodeRedux evolves the ideas of [Redux](https://redux.js.org/),
|
||||
which help to maintain state lua base app basically NodeMCU devices.
|
||||
|
||||
## Basic Example
|
||||
|
||||
The whole global state of your app is stored in an object tree inside a single _store_.
|
||||
The only way to change the state tree is to create an _action_,
|
||||
an object describing what happened, and _dispatch_ it to the store.
|
||||
To specify how state gets updated in response to an action, you write pure _reducer_
|
||||
functions that calculate a new state based on the old state and the action.
|
||||
|
||||
|
||||
```lua
|
||||
local redux = require('redux') -- optional line for nodemcu, only need for lua app
|
||||
|
||||
-- This is a reducer - a function that takes a current state value and an
|
||||
-- action object describing "what happened", and returns a new state value.
|
||||
-- A reducer's function signature is: (state, action) => newState
|
||||
--
|
||||
-- The NodeRedux state should contain only plain Lua table.
|
||||
-- The root state value is usually an table. It's important that you should
|
||||
-- not mutate the state table, but return a new table if the state changes.
|
||||
--
|
||||
-- You can use any conditional logic you want in a reducer. In this example,
|
||||
-- we use a if statement, but it's not required.
|
||||
|
||||
local function counterReducer(state, action)
|
||||
state = state or { value = 0 }
|
||||
if action.type == 'counter/incremented' then
|
||||
return { value = state.value + 2 }
|
||||
elseif action.type == 'counter/decremented' then
|
||||
return { value = state.value - 1 }
|
||||
else
|
||||
return state
|
||||
end
|
||||
end
|
||||
|
||||
redux.createStore(counterReducer)
|
||||
|
||||
local function console(pState, cState)
|
||||
print('Previous State: '.. pState.value, 'Current State: '.. cState.value)
|
||||
end
|
||||
|
||||
redux.store.subscribe(console)
|
||||
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {value = 1}
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {value = 2}
|
||||
redux.store.dispatch({type = 'counter/decremented'})
|
||||
-- {value = 1}
|
||||
```
|
||||
|
||||
[Here](../../lua_modules/node_redux/createStore_example.lua) the example code
|
||||
|
||||
### Require
|
||||
```lua
|
||||
local redux = require("node_redux")
|
||||
```
|
||||
|
||||
## redux.createStore()
|
||||
Creates a Redux store that holds the complete state tree of device. There should only be a single store in your device.
|
||||
|
||||
#### Syntax
|
||||
`redux.createStore(reducer)`
|
||||
|
||||
#### Parameters
|
||||
- `reducer`(Function): A reducing function that returns the next state tree,
|
||||
given the current state tree, and an action to handle.
|
||||
- `preloadedState`(any): The initial state. You may optionally specify it to
|
||||
hydrate the state from the server in universal apps, or to restore a previously
|
||||
serialized user session. If you produced reducer with combineReducers, this must
|
||||
be a plain object with the same shape as the keys passed to it. Otherwise,
|
||||
you are free to pass anything that your reducer can understand.
|
||||
- `enhancer` (Function): The store enhancer. You may optionally specify it to
|
||||
enhance the store with third-party capabilities such as middleware, time travel,
|
||||
persistence, etc. The only store enhancer that ships with Redux is
|
||||
applyMiddleware() ***TODO: Support added in near next PR***
|
||||
|
||||
#### Returns
|
||||
- `nil`
|
||||
|
||||
## redux.combineReducers()
|
||||
As your app grows more complex, you'll want to split your reducing function into
|
||||
separate functions, each managing independent parts of the state.
|
||||
The combineReducers helper function turns an object whose values are different
|
||||
reducing functions into a single reducing function you can pass to createStore.
|
||||
|
||||
#### Syntax
|
||||
```lua
|
||||
redux.combineReducers({
|
||||
reducer_one = reducer_1,
|
||||
reducer_two = reducer_2,
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
- `table`(Table of Functions values): A reducing functions that returns the next
|
||||
state tree, given the current state tree, and an action to handle.
|
||||
#### Returns
|
||||
|
||||
- `combined_reducer` (Function) A single combined reducer build by combining
|
||||
all reducers
|
||||
|
||||
#### Example
|
||||
|
||||
```lua
|
||||
local redux = require('redux') -- optional line for nodemcu, only need for lua app
|
||||
|
||||
-- This is a reducer - a function that takes a current state value and an
|
||||
-- action object describing "what happened", and returns a new state value.
|
||||
-- A reducer's function signature is: (state, action) => newState
|
||||
--
|
||||
-- The NodeRedux state should contain only plain Lua table.
|
||||
-- The root state value is usually an table. It's important that you should
|
||||
-- not mutate the state table, but return a new table if the state changes.
|
||||
--
|
||||
-- You can use any conditional logic you want in a reducer. In this example,
|
||||
-- we use a if statement, but it's not required.
|
||||
|
||||
local function counterReducer(state, action)
|
||||
state = state or { value = 0 }
|
||||
if action.type == 'counter/incremented' then
|
||||
return { value = state.value + 2 }
|
||||
elseif action.type == 'counter/decremented' then
|
||||
return { value = state.value - 1 }
|
||||
else
|
||||
return state
|
||||
end
|
||||
end
|
||||
|
||||
local function inverseCounterReducer(state, action)
|
||||
state = state or { value = 0 }
|
||||
if action.type == 'counter/incremented' then
|
||||
return { value = state.value - 1 }
|
||||
elseif action.type == 'counter/decremented' then
|
||||
return { value = state.value + 1 }
|
||||
else
|
||||
return state
|
||||
end
|
||||
end
|
||||
|
||||
local reducer = redux.combineReducers({
|
||||
counterReducer = counterReducer,
|
||||
inverseCounterReducer = inverseCounterReducer,
|
||||
})
|
||||
|
||||
redux.createStore(reducer)
|
||||
|
||||
local function console(pState, cState)
|
||||
print('Previous State: counterReducer' ..
|
||||
pState.counterReducer.value,
|
||||
'Current State: counterReducer' ..
|
||||
cState.counterReducer.value
|
||||
)
|
||||
print('Previous State: inverseCounterReducer' ..
|
||||
pState.inverseCounterReducer.value,
|
||||
'Current State: inverseCounterReducer' ..
|
||||
cState.inverseCounterReducer.value
|
||||
)
|
||||
end
|
||||
|
||||
redux.store.subscribe(console)
|
||||
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {counterReducer = { value = 2 }, inverseCounterReducer = { value = -1 } }
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {counterReducer = { value = 4 }, inverseCounterReducer = { value = -2 } }
|
||||
redux.store.dispatch({type = 'counter/decremented'})
|
||||
-- {counterReducer = { value = 3 }, inverseCounterReducer = { value = -1 } }
|
||||
```
|
||||
|
||||
## redux.store.getState()
|
||||
Returns the current state tree of your application. It is equal to the last value
|
||||
returned by the store's reducer.
|
||||
#### Syntax
|
||||
`redux.store.getState()`
|
||||
|
||||
#### Parameters
|
||||
None
|
||||
|
||||
#### Returns
|
||||
The current state tree of your application.
|
||||
|
||||
## redux.store.dispatch()
|
||||
Dispatches an action. This is the only way to trigger a state change.
|
||||
|
||||
The store's reducing function will be called with the current getState() result,
|
||||
and the given action synchronously. Its return value will be considered the next state.
|
||||
It will be returned from getState() from now on, and the change listeners will
|
||||
immediately be notified.
|
||||
#### Syntax
|
||||
`redux.store.dispatch(action)`
|
||||
|
||||
#### Parameters
|
||||
- `action` (_Table_): A plain object describing the change that makes sense for
|
||||
your application. Actions must have a type field that indicates the `type`
|
||||
of action being performed. Types can be defined as constants and imported
|
||||
from another module. It's better to use strings for `type` than Symbols
|
||||
because strings are serializable.
|
||||
|
||||
#### Returns
|
||||
(_Table_): The dispatched action
|
||||
|
||||
## redux.store.subscribe()
|
||||
Adds a change listener. It will be called any time an action is dispatched, and some
|
||||
part of the state tree may potentially have changed. You may then use `1st arg` for
|
||||
previous state and `2nd arg` for current state.
|
||||
|
||||
- The listener should only call dispatch() either in response to user actions or
|
||||
under specific conditions (e.g. dispatching an action when the store has
|
||||
a specific field). Calling dispatch() without any conditions is technically
|
||||
possible, however it leads to an infinite loop as every dispatch() call
|
||||
usually triggers the listener again.
|
||||
|
||||
#### Syntax
|
||||
`redux.store.subscribe(listener)`
|
||||
|
||||
#### Parameters
|
||||
- `listener` (Function): The callback to be invoked any time an action has been
|
||||
dispatched, and the state tree might have changed. You may then use `1st arg` for
|
||||
previous state and `2nd arg` for current state
|
||||
|
||||
#### Example - listener
|
||||
```lua
|
||||
local function listener(pState, cState)
|
||||
print('Previous State: counterReducer' ..
|
||||
pState.counterReducer.value,
|
||||
'Current State: counterReducer' ..
|
||||
cState.counterReducer.value
|
||||
)
|
||||
print('Previous State: inverseCounterReducer' ..
|
||||
pState.inverseCounterReducer.value,
|
||||
'Current State: inverseCounterReducer' ..
|
||||
cState.inverseCounterReducer.value
|
||||
)
|
||||
end
|
||||
```
|
||||
|
||||
## redux.store.replaceReducer()
|
||||
It is an advanced API. You might need this if your app implements code
|
||||
splitting, and you want to load some of the reducers dynamically.
|
||||
You might also need this if you implement a hot reloading mechanism for Redux.
|
||||
|
||||
#### Syntax
|
||||
`redux.store.replaceReducer(nextReducer)`
|
||||
|
||||
#### Parameters
|
||||
- `nextReducer` (Function): The next reducer for the store to use.
|
|
@ -1,66 +1,3 @@
|
|||
# NodeRedux
|
||||
Redux is a predictable state container for lua apps and NodeMCU.
|
||||
|
||||
## Influences
|
||||
|
||||
NodeRedux evolves the ideas of [Redux](https://redux.js.org/),
|
||||
which help to maintain state lua base app basically NodeMCU devices.
|
||||
|
||||
|
||||
## Basic Example
|
||||
|
||||
The whole global state of your app is stored in an object tree inside a single _store_.
|
||||
The only way to change the state tree is to create an _action_,
|
||||
an object describing what happened, and _dispatch_ it to the store.
|
||||
To specify how state gets updated in response to an action, you write pure _reducer_
|
||||
functions that calculate a new state based on the old state and the action.
|
||||
|
||||
|
||||
```lua
|
||||
local redux = require('redux') -- optional line for nodemcu, only need for lua app
|
||||
|
||||
-- This is a reducer - a function that takes a current state value and an
|
||||
-- action object describing "what happened", and returns a new state value.
|
||||
-- A reducer's function signature is: (state, action) => newState
|
||||
--
|
||||
-- The NodeRedux state should contain only plain Lua table.
|
||||
-- The root state value is usually an table. It's important that you should
|
||||
-- not mutate the state table, but return a new table if the state changes.
|
||||
--
|
||||
-- You can use any conditional logic you want in a reducer. In this example,
|
||||
-- we use a if statement, but it's not required.
|
||||
|
||||
local function counterReducer(state, action)
|
||||
state = state or { value = 0 }
|
||||
if action.type == 'counter/incremented' then
|
||||
return { value = state.value + 2 }
|
||||
elseif action.type == 'counter/decremented' then
|
||||
return { value = state.value - 1 }
|
||||
else
|
||||
return state
|
||||
end
|
||||
end
|
||||
|
||||
redux.createStore(counterReducer)
|
||||
|
||||
local function console(pState, cState)
|
||||
print('Previous State: '.. pState.value, 'Current State: '.. cState.value)
|
||||
end
|
||||
|
||||
redux.store.subscribe(console)
|
||||
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {value = 1}
|
||||
redux.store.dispatch({type = 'counter/incremented'})
|
||||
-- {value = 2}
|
||||
redux.store.dispatch({type = 'counter/decremented'})
|
||||
-- {value = 1}
|
||||
```
|
||||
|
||||
[Here](./createStore_example.lua) the example code
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
# NodeRedux Module
|
||||
|
||||
Documentation for this Lua module is available in the [node_redux.md](../../docs/lua-modules/node_redux.md) file and in the [Official NodeMCU Documentation](https://nodemcu.readthedocs.io/) in `Lua Modules` section.
|
||||
|
|
Loading…
Reference in New Issue