Vivy is a JavaScript state container built on redux that simplifies development by adopting a syntax similar to Redux.
In Vivy, the state
, actions
, and reducers
are combined into a single Object
called the model
. Both actions
and reducers
within the model
can be invoked using the dispatch
function. Consequently, there's no need to define
specific action types
in Vivy. Additionally, redundant actions
become unnecessary as you can directly dispatch
reducers
.
Vivy is designed with expandability in mind. You can easily handle routing using vivy-router, and effortlessly load components and models on-demand with vivy-async-component. The vivy-api facilitates API requests, while vivy-subscription allows you to observe changes in history or other events and update the state by dispatching a reducer or action. Furthermore, vivy-i18n assists you in implementing internationalization (i18n) functionality.
Using NPM
:
$ npm install vivy
$ cd ./examples/[EXAMPLE_NAME]
$ npm run start
Example names:
Plugin | Version | Description |
---|---|---|
react‑vivy | React bindings for Vivy based on react-redux. |
Plugin | Version | Description |
---|---|---|
vivy‑router | A router plugin based on connected-react-router. | |
vivy‑async‑component | A plugin which loading async component and async Vivy model to easily split chunks by route. | |
vivy‑api | Handle apis in Vivy model to make api calling easier. |
|
vivy‑subscription | Handle subscriptions in Vivy model to watch history or something else. |
|
vivy‑i18n | Handle i18ns in Vivy model to implement i18n. |
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-vivy';
// Import Vivy
import Vivy from 'vivy';
// Import Vivy model
import yourVivyModel from 'path_to_your_vivy_model';
// Create Vivy instance
const vivy = Vivy();
// Get Vivy Store
const store = vivy.createStore();
// Register Vivy model
store.registerModel(yourVivyModel);
// Render
render(
<Provider store={store}>
<Root/>
</Provider>,
document.getElementById('app-container')
);
A Vivy model is an Object
combined state
, actions
, globalReducers
and reducers
.
const yourVivyModel = {
// An unique key registered to store.
nameSpace: 'yourVivyModel',
// Any type of redux state value.
state: STATE_VALUE,
// Vivy model action.
actions: {
// Define a model action. Payload here is an object passing by dispatch
ACTION_NAME: payload => (dispatch, getState) => {
// Get state value by getState.
const state = getState();
const STATE_VALUE = state.MODEL_NAME_SPACE
// Dispatch an action
dispatch({
type: 'MODEL_NAME_SPACE/OTHER_ACTION_NAME',
// payload ...
});
// Dispatch a global reducer.
dispatch({
type: 'GLOBAL_REDUCER_NAME',
// payload ...
});
// Dispatch a reducer
dispatch({
type: 'MODEL_NAME_SPACE/REDUCER_NAME',
// payload ...
});
},
// Register another model action.
OTHER_ACTION_NAME: payload => (dispatch, getState) => {
// dispatch some actions or reducers.
}
// Other actions ...
},
// Vivy model global reducer.
globalReducers: {
// Register a global reducer.
// The reducer will be registered to global without current model namespace.
//
// Example:
// dispatch({
// type: 'GLOBAL_REDUCER_NAME',
// // payloads ...
// });
GLOBAL_REDUCER_NAME: (state, payload) => {
return {
...state,
// Do something by payload.
};
},
// Other global reducers ...
},
// Vivy model reducer.
reducers: {
// Register a reducer.
//
// Example:
// store.dispatch({
// type: 'MODEL_NAME_SPACE/GLOBAL_REDUCER_NAME',
// // payloads ...
// });
REDUCER_NAME: (state, payload) => {
return {
...state,
// Do something by payload.
};
},
// Other reducers ...
}
}
In Vivy, you can use 4 ways to dispatch an action.
- Use hook "useModel" from react-vivy.
import {useModel} from 'react-vivy';
const App = () => {
// ...
/**
* Get state and actions/reducers from model using hook "useModel".
*/
const [modelState, modelActions] = useModel('MODEL_OR_NAME_SPACE');
/**
* Call the action or reducer.
*/
modelActions.someAction();
// ...
};
export default App;
- Use
store.dispatch
function.
dispatch({
type: 'MODEL_NAME_SPACE/ACTION_OR_REDUCER_NAME',
OTHER_PROPS
});
- Use
store.dispatch
chain function.
dispatch.MODEL_NAME_SPACE.ACTION_OR_REDUCER_NAME({
OTHER_PROPS
});
- Use
bindModelActionCreators
to create an action dispatcher.
import {bindModelActionCreators} from 'vivy';
const App = () => {
// ...
ACTION_OR_REDUCER_NAME({
OTHER_PROPS
});
// ...
}
export default connect(state => ({
// states
}), dispatch => bindModelActionCreators({
ACTION_OR_REDUCER_NAME: 'MODEL_NAME_SPACE/ACTION_OR_REDUCER_NAME'
}, dispatch))(App);
import React from 'react';
import {useModel} from 'react-vivy';
const App = () => {
/**
* Get state and actions/reducers from model using hook "useModel".
*/
const [{value}, {updateValue}] = useModel('MODEL_OR_NAME_SPACE');
return (
<input value={value}
onChange={e => updateValue({
value: e.target.value
})}/>
);
};
export default App;
For more hooks usage documents, please check react-vivy.
registerReducer(vivyStore, nameSpace, reducer)
Example:
import {registerReducer} from 'vivy';
// Register a Redux reudcer to your Vivy store
registerReducer(YOUR_VIVY_STORE, YOUR_REDUCER_NAME_SAPCE, YOUR_REDUX_REDUCER);
registerReducers(vivyStore, reducers)
Example:
import {registerReducers} from 'vivy';
// Register Redux reudcers to your Vivy store
registerReducers(YOUR_VIVY_STORE, {
YOUR_REDUCER_NAME_SAPCE_1: YOUR_REDUX_REDUCER_1,
YOUR_REDUCER_NAME_SAPCE_2: YOUR_REDUX_REDUCER_2,
// other reducers...
});
registerModel(vivyStore, model)
Example:
import {registerModel} from 'vivy';
// Register a Vivy model to your Vivy store
registerModel(YOUR_VIVY_STORE, YOUR_VIVY_MODEL);
registerModels(vivyStore, models)
Example:
import {registerModels} from 'vivy';
// Register Vivy models to your Vivy store
registerModels(YOUR_VIVY_STORE, [
YOUR_VIVY_MODEL_1,
YOUR_VIVY_MODEL_2,
// other models...
]);
unregisterReducer(vivyStore, nameSpace)
Example:
import {unregisterReducer} from 'vivy';
// Unregister a Redux reducer from your Vivy store
unregisterReducer(YOUR_VIVY_STORE, YOUR_REDUCER_NAME_SAPCE);
unregisterReducers(vivyStore, nameSpaces)
Example:
import {unregisterReducers} from 'vivy';
// Unregister Redux reducers from your Vivy store
unregisterReducers(YOUR_VIVY_STORE, [
YOUR_REDUCER_NAME_SAPCE_1,
YOUR_REDUCER_NAME_SAPCE_2,
// other reducers name space...
]);
unregisterModel(vivyStore, model)
Example:
import {unregisterModel} from 'vivy';
// Unregister a Vivy model from your Vivy store
unregisterModel(YOUR_VIVY_STORE, YOUR_VIVY_MODEL);
unregisterModels(vivyStore, models)
Example:
import {unregisterModels} from 'vivy';
// Unregister Vivy models from your Vivy store
unregisterModels(YOUR_VIVY_STORE, [
YOUR_VIVY_MODEL_1,
YOUR_VIVY_MODEL_2,
// other models...
]);
bindModelActionCreators(modelActionCreators, dispatch)
Example:
import React from 'react';
import {connect} from 'react-vivy';
import {bindModelActionCreators} from 'vivy';
const App = ({
MODEL_STATE, MODEL_ACTION
}) => (
<div>App</div>
);
export default connect(state => ({
MODEL_STATE: state.MODEL_NAMESPACE,
}), dispatch => bindModelActionCreators({
MODEL_ACTION: 'MODEL_NAMESPACE/MODEL_ACTION_KEY',
}, dispatch))(App);