# Use umi with dva
As of >= umi@2, we recommend using umi-plugin-react for dva integration.
# Features
- Model loading by directory, getting rid of
app.model - File name as namespace,
namespaceas model key will be exported byumi - No manually defined router.js,
umiwill take over the router stuff, and bothmodels andcomponents can be loaded on demand - Built-in query-string handler, manually encoding and decoding URL are not required any more
- Built-in dva-loading and dva-immer support, of which
dva-immercan be enabled via configuration - Out of box, dependencies such as:
dva,dva-loading,dva-immer,path-to-regexp,object-assign,react,react-domare built in, so that you don't have to worry about them
# Usage
Install via yarn,
$ yarn add umi-plugin-react
Install via npm, using the command npm install --save umi-plugin-react.
Add configuration in .umirc.js:
export default {
plugins: [
[
'umi-plugin-react',
{
dva: true,
},.
]
],
};
Enable dva-immer for elegant reducer writing experience
export default {
plugins: [
[
'umi-plugin-react',
{
dva: {
immer: true
}
}
],
],
};
# Registering models
There are two types of models: the globally registered (global) model, and the page-level model.
The global model should be defined in /src/models/, and can be referenced in all other pages.
The page-level model should not be used in any other page.
Model loading rules:
src/models/**/*.jsare defined as global modelssrc/pages/**/models/**/*.jsare defined as page-level models- global models will be loaded along with the application; page-level models are loaded on demand while in
productionbuild (both will always be loaded indevelopmentbuild) - page-level models can be
.jsfiles inmodels/**/*.jspattern - page-level models can be scanned upward to app structure, For example: if you have page
.jslikepages/a/b.js, its page-level model shall bepages/a/b/models/**/*.js+pages/a/models/**/*.js... - if
model.jsis defined, the page should be a single-file-model, which means you don't have to createmodelsdirectory if you have only one model. So if you havemodel.jsdefined, all.jsfiles defined inmodels/**/*.jswill be ignored
Example:
+ src
+ models
- g.js
+ pages
+ a
+ models
- a.js
- b.js
+ ss
- s.js
- page.js
+ c
- model.js
+ d
+ models
- d.js
- page.js
- page.js
With the above file structure:
- the global model is
src/models/g.js - the page-level models for
/aissrc/pages/a/models/{a,b,ss/s}.js - the page-level model for
/cissrc/pages/c/model.js - the page-level models for
/c/daresrc/pages/c/model.js, src/pages/c/d/models/d.js
# Configuration and plugins
The previous configuration in
src/dva.jshas been deprecated, and will remove support in next major release.
Create a new app.js in the src directory with the following contents:
export const dva = {
config: {
onError(e) {
e.preventDefault();
console.error(e.message);
},
},
plugins: [
require('dva-logger')(),
],
};
# FAQ
# Page component is not re-rendered whenever url changed?
If you have connect data in layouts/index.js, umi/withRouter is required
import withRouter from 'umi/withRouter';
export default withRouter(connect(mapStateToProps)(LayoutComponent));
# How to access store or dispatch?
window.g_app._store
window.g_app._store.dispatch
# How to disable load on demand for component and models?
Add config to .umirc.js:
export default {
plugins: [
[
'umi-plugin-react',
{
dva: {
dynamicImport: undefined // config in dva
},
dynamicImport: undefined // root config will be inherited as well
}
],
],
};
# Page component is not re-rendered whenever url is changed while connect data in layout
Check the order of connect, withRouter usage
import withRouter from 'umi/withRouter';
export default withRouter(connect()(Layout));