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,
namespace
as model key will be exported byumi
- No manually defined router.js,
umi
will take over the router stuff, and bothmodel
s andcomponent
s 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-immer
can be enabled via configuration - Out of box, dependencies such as:
dva
,dva-loading
,dva-immer
,path-to-regexp
,object-assign
,react
,react-dom
are 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/**/*.js
are defined as global modelssrc/pages/**/models/**/*.js
are defined as page-level models- global models will be loaded along with the application; page-level models are loaded on demand while in
production
build (both will always be loaded indevelopment
build) - page-level models can be
.js
files inmodels/**/*.js
pattern - page-level models can be scanned upward to app structure, For example: if you have page
.js
likepages/a/b.js
, its page-level model shall bepages/a/b/models/**/*.js
+pages/a/models/**/*.js
... - if
model.js
is defined, the page should be a single-file-model, which means you don't have to createmodels
directory if you have only one model. So if you havemodel.js
defined, all.js
files defined inmodels/**/*.js
will 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
/a
issrc/pages/a/models/{a,b,ss/s}.js
- the page-level model for
/c
issrc/pages/c/model.js
- the page-level models for
/c/d
aresrc/pages/c/model.js, src/pages/c/d/models/d.js
Configuration and plugins
The previous configuration in
src/dva.js
has 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));
store
or dispatch
?
How to access window.g_app._store
window.g_app._store.dispatch
component
and models
?
How to disable load on demand for 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
}
],
],
};
connect
data in layout
Page component is not re-rendered whenever url is changed while Check the order of connect
, withRouter
usage
import withRouter from 'umi/withRouter';
export default withRouter(connect()(Layout));