### Install dva-cli
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Installs the dva command-line interface globally. Ensure you have version 0.9.1 or higher.
```bash
$ npm install dva-cli -g
$ dva -v
```
--------------------------------
### DvaJS Project Setup and Model Definition
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This is a comprehensive example of a DvaJS application setup. It includes the initialization of the Dva app, the definition of a 'count' model with state, reducers, effects, and subscriptions, the connection of a React component to the model using `connect`, and the configuration of the router. It also includes the helper `delay` function.
```javascript
import dva, { connect } from 'dva';
import { Router, Route } from 'dva/router';
import React from 'react';
import styles from './index.less';
import key from 'keymaster';
const app = dva();
app.model({
namespace: 'count',
state: {
record: 0,
current: 0,
},
reducers: {
add(state) {
const newCurrent = state.current + 1;
return { ...state,
record: newCurrent > state.record ? newCurrent : state.record,
current: newCurrent,
};
},
minus(state) {
return { ...state, current: state.current - 1};
},
},
effects: {
*addThenMinus(action, { call, put }) {
yield put({ type: 'add' });
yield call(delay, 1000);
yield put({ type: 'minus' });
},
},
subscriptions: {
keyboardWatcher({ dispatch }) {
key('⌘+up, ctrl+up', () => { dispatch({type:'addThenMinus'}) });
},
},
});
const CountApp = ({count, dispatch}) => {
return (
Highest Record: {count.record}
{count.current}
);
};
function mapStateToProps(state) {
return { count: state.count };
}
const HomePage = connect(mapStateToProps)(CountApp);
app.router(({history})
);
app.start('#root');
// ---------
// Helpers
function delay(timeout){
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
```
--------------------------------
### Start Development Server
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Navigates into the project directory and starts the development server.
```bash
$ cd dva-quickstart
$ npm start
```
--------------------------------
### Install dva-cli
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Installs the Dva command-line interface globally using npm. This tool is essential for creating and managing Dva applications.
```bash
npm install -g dva-cli
```
--------------------------------
### Install Ant Design and Babel Plugin
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Installs Ant Design (antd) and babel-plugin-import for on-demand loading of antd components.
```bash
$ npm install antd babel-plugin-import --save
```
--------------------------------
### Start Dva Development Server
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Navigates into the created application directory and starts the development server. The app will be accessible at http://localhost:8000.
```bash
cd myapp
npm start
```
--------------------------------
### Create New Dva Application
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Creates a new Dva project named 'dva-quickstart' with a pre-configured development environment.
```bash
$ dva new dva-quickstart
```
--------------------------------
### DvaJS Dependency Installation via CLI
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This output demonstrates how the DvaJS CLI automatically installs project dependencies. When `keymaster` was imported in the code, the CLI detected it and proceeded to install it using npm, updating the `package.json` file. This simplifies dependency management for the developer.
```bash
use npm: tnpm
Installing `keymaster`...
[keymaster@*] installed at node_modules/.npminstall/keymaster/1.6.2/keymaster (1 packages, use 745ms, speed 24.06kB/s, json 2.98kB, tarball 15.08kB)
All packages installed (1 packages installed from npm registry, use 755ms, speed 23.93kB/s, json 1(2.98kB), tarball 15.08kB)
📦 2/2 build modules
webpack: bundle build is now finished.
```
--------------------------------
### Load Products Model
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Registers the 'products' model with the Dva application instance.
```diff
// 3. Model
+ app.model(require('./models/products').default);
```
--------------------------------
### Build Application for Production
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Builds an optimized production-ready version of the Dva application. The output files are placed in the 'dist/' directory.
```bash
$ npm run build
```
--------------------------------
### Set Initial State
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Initializes the Dva application state with sample product data.
```diff
- const app = dva();
+ const app = dva({
+ initialState: {
+ products: [
+ { name: 'dva', id: 1 },
+ { name: 'antd', id: 2 },
+ ],
+ },
+ });
```
--------------------------------
### Creating a Dva Project with Dva-CLI
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Provides instructions on how to install and use `dva-cli` to create a new Dva project. It covers global installation, project creation, navigating into the project directory, and starting the development server.
```bash
$ npm install dva-cli -g
$ dva new myapp
$ cd myapp
$ npm start
```
--------------------------------
### CSS Modules for Styling
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Provides an example of CSS styling using CSS Modules, as integrated with DvaJS. It defines styles for elements like `.normal`, `.record`, `.current`, and `.button`, including nested styles for buttons.
```css
.normal {
width: 200px;
margin: 100px auto;
padding: 20px;
border: 1px solid #ccc;
box-shadow: 0 0 20px #ccc;
}
.record {
border-bottom: 1px solid #ccc;
padding-bottom: 8px;
color: #ccc;
}
.current {
text-align: center;
font-size: 40px;
padding: 40px 0;
}
.button {
text-align: center;
button {
width: 100px;
height: 40px;
background: #aaa;
color: #fff;
}
}
```
--------------------------------
### Create New Dva App
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Creates a new Dva application named 'myapp'. The `--demo` flag is used for creating demo-level applications; omit it for standard projects.
```bash
dva new myapp --demo
```
--------------------------------
### DvaJS Reducer Example
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Demonstrates how to define reducers in a DvaJS model to update the application state. It shows the structure of a reducer function, which takes the current state and an action, and returns a new state. The example includes 'add' and 'minus' reducers for a 'count' model.
```javascript
app.model({
namespace: 'count',
state: {
record: 0,
current: 0,
},
reducers: {
add(state) {
const newCurrent = state.current + 1;
return { ...state,
record: newCurrent > state.record ? newCurrent : state.record,
current: newCurrent,
};
},
minus(state) {
return { ...state, current: state.current - 1};
},
},
});
```
--------------------------------
### Install and Run with npm
Source: https://github.com/dvajs/dva/blob/master/examples/with-redux-undo/README.md
Installs project dependencies using npm and starts the development server. The application can then be viewed at http://localhost:1234.
```bash
npm install
npm start
```
--------------------------------
### Define Product Route
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Defines a new route for the 'Products' page in the application's router configuration.
```diff
+ import Products from './routes/Products';
...
+
```
--------------------------------
### Install and Run with Yarn
Source: https://github.com/dvajs/dva/blob/master/examples/with-redux-undo/README.md
Installs project dependencies using Yarn and starts the development server. The application can then be viewed at http://localhost:1234.
```bash
yarn
yarn start
```
--------------------------------
### DvaJS Subscription: Keyboard Event Listener
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This snippet shows how to subscribe to keyboard events in DvaJS using the `subscriptions` API. It utilizes the `keymaster` library to listen for a specific key combination ('⌘+up' or 'ctrl+up') and dispatches the `addThenMinus` action when the combination is detected. DvaJS automatically handles the installation of `keymaster` if it's not already a dependency.
```javascript
import key from 'keymaster';
app.model({
namespace: 'count',
subscriptions: {
keyboardWatcher({ dispatch }) {
key('⌘+up, ctrl+up', () => { dispatch({type:'addThenMinus'}) });
},
},
});
```
--------------------------------
### Connect Component to Dva Store
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Connects the Products component to the Dva store, allowing it to dispatch actions and access the 'products' state.
```javascript
import React from 'react';
import { connect } from 'dva';
import ProductList from '../components/ProductList';
const Products = ({ dispatch, products }) => {
function handleDelete(id) {
dispatch({
type: 'products/delete',
payload: id,
});
}
return (
List of Products
);
};
// export default Products;
export default connect(({ products }) => ({
products,
}))(Products);
```
--------------------------------
### Build Dva Application
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This command initiates the build process for a Dva application, preparing it for deployment. It typically uses a build tool like `atool-build` to bundle and optimize the application's assets.
```bash
$ npm run build
> @ build /private/tmp/dva-quickstart
> atool-build
Child
Time: 6891ms
Asset Size Chunks Chunk Names
common.js 1.18 kB 0 [emitted] common
index.js 281 kB 1, 0 [emitted] index
index.css 353 bytes 1, 0 [emitted] index
```
--------------------------------
### Start Server
Source: https://github.com/dvajs/dva/blob/master/examples/user-dashboard/README.md
Starts the development server to run the application. The app will automatically open in the default browser upon successful startup.
```bash
npm start
```
--------------------------------
### Install Dependencies
Source: https://github.com/dvajs/dva/blob/master/examples/user-dashboard/README.md
Installs the necessary project dependencies using npm.
```bash
npm install
```
--------------------------------
### Configure Babel Plugin for Ant Design
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Configures `.webpackrc` to enable `babel-plugin-import` for antd, allowing for optimized loading of styles and scripts.
```diff
{
+ "extraBabelPlugins": [
+ ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
+ ]
}
```
--------------------------------
### Define Products Model
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
Defines a Dva model for managing product data, including state, reducers for state updates (like deleting a product), and effects for asynchronous operations.
```javascript
export default {
namespace: 'products',
state: [],
reducers: {
'delete'(state, { payload: id }) {
return state.filter(item => item.id !== id);
},
},
};
```
--------------------------------
### dva CLI - Project Setup
Source: https://github.com/dvajs/dva/blob/master/README_zh-CN.md
The dva CLI provides a command-line interface for creating and managing dva projects. It simplifies the setup process, including configuration and build tools.
```bash
# Install dva-cli globally
npm install -g dva-cli
# Create a new dva project
dva new my-app
# Navigate to the project directory
cd my-app
# Start the development server
npm start
# Build for production
npm run build
```
--------------------------------
### DvaJS Router Configuration
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Shows how to define the application's routing using DvaJS. It configures a basic router with a single route that maps the root path '/' to the `HomePage` component, utilizing the provided `history` object.
```javascript
app.router(({history}) =>
);
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/dvajs/dva/blob/master/examples/with-nextjs/README.md
Installs all necessary project dependencies using npm. Ensure you have Node.js and npm installed.
```bash
npm install
```
--------------------------------
### Product List UI Component
Source: https://github.com/dvajs/dva/blob/master/docs/guide/getting-started.md
A React component for displaying a list of products using Ant Design's Table and Button components. It includes functionality for deleting products.
```javascript
import React from 'react';
import PropTypes from 'prop-types';
import { Table, Popconfirm, Button } from 'antd';
const ProductList = ({ onDelete, products }) => {
const columns = [{
title: 'Name',
dataIndex: 'name',
}, {
title: 'Actions',
render: (text, record) => {
return (
onDelete(record.id)}>
);
},
}];
return (
);
};
ProductList.propTypes = {
onDelete: PropTypes.func.isRequired,
products: PropTypes.array.isRequired,
};
export default ProductList;
```
--------------------------------
### dva API - `app.start()`
Source: https://github.com/dvajs/dva/blob/master/README_zh-CN.md
The `app.start()` method starts the dva application and mounts the root component to a specified DOM element. It should be called after all models have been registered.
```APIDOC
app.start(container)
Parameters:
container: string | HTMLElement (required) - A CSS selector or DOM element where the root component will be mounted.
Returns:
Object - The dva app instance for chaining.
```
--------------------------------
### Subscription Example with keymaster
Source: https://github.com/dvajs/dva/blob/master/docs/guide/concepts.md
An example of using subscriptions to listen for external events, like keyboard shortcuts, and dispatch actions.
```javascript
import key from 'keymaster';
...
app.model({
namespace: 'count',
subscriptions: {
keyEvent({dispatch}) {
key('⌘+up, ctrl+up', () => { dispatch({type:'add'}) });
},
}
});
```
--------------------------------
### Start Application
Source: https://github.com/dvajs/dva/blob/master/docs/API.md
Starts the Dva application. Optionally accepts a selector to mount the application. If no selector is provided, it returns a function that returns the JSX element for the application.
```javascript
app.start('#root');
```
```javascript
import { IntlProvider } from 'react-intl';
...
const App = app.start();
ReactDOM.render(, htmlElement);
```
--------------------------------
### Start the Application
Source: https://github.com/dvajs/dva/blob/master/examples/with-nextjs/README.md
Starts the Next.js application with dva.js integration. This command typically runs a development server.
```bash
npm start
```
--------------------------------
### Dva App Creation
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
Demonstrates the creation of a Dva app instance by calling `core.create` with options and initial reducers. The `app` object includes methods for managing models and starting the application.
```javascript
export function create(hooksAndOpts = {}, createOpts = {}) {
const {
initialReducer,
setupApp = noop,
} = createOpts;
const plugin = new Plugin();
plugin.use(filterHooks(hooksAndOpts));
const app = {
_models: [
prefixNamespace({ ...dvaModel }),
],
_store: null,
_plugin: plugin,
use: plugin.use.bind(plugin),
model,
start,
};
return app;
// ....
function model(){
// model 方法
}
functoin start(){
// Start 方法
}
}
```
--------------------------------
### 使用 call 方法实现代理模式
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
演示了 Dva 如何使用 `call` 方法来代理 `dva-core` 实例化的 `app` 对象的 `start` 方法,从而在 `start` 方法中注入视图层逻辑。
```javascript
export default function(opts = {}) {
// ...初始化 route ,和添加 route 中间件的方法。
/**
* 1. 新建 function ,函数内实例化一个 app 对象。
*
*/
const app = core.create(opts, createOpts);
/**
* 2. 新建变量指向该对象希望代理的方法
*
*/
const oldAppStart = app.start;
app.router = router;
/**
* 4. 令 app.start = start,完成对 app 对象的 start 方法的代理。
* @type {[type]}
*/
app.start = start;
return app;
// router 赋值
/**
* 3.1 新建同名方法 start,
*
*/
function start(container) {
// 合法性检测代码
/**
* 3.2 在其中使用 call,指定 oldStart 的调用者为 app。
*/
oldAppStart.call(app);
// 因为有 3.2 的执行才有现在的 store
const store = app._store;
// 使用高阶组件创建视图
}
}
```
--------------------------------
### Starting Dva Application
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Starts the Dva application. If a selector is provided, it mounts the app to the specified DOM element. If no selector is provided, it returns a function that returns a JSX element, useful for testing, React Native, or internationalization.
```js
app.start('#root');
```
```js
import { IntlProvider } from 'react-intl';
...
const App = app.start();
ReactDOM.render(, htmlElement);
```
--------------------------------
### Package.json 启动脚本
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
展示了 Dva 项目中 `package.json` 文件里 `scripts` 部分的 `start` 命令,该命令通过 `roadhog server` 来启动开发服务器。
```json
{
"scripts": {
"start": "roadhog server"
}
}
```
--------------------------------
### Redux Store Creation Example
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
This snippet illustrates the typical method for creating a Redux store, showing how reducers, middleware, and initial state are combined using `createStore`.
```javascript
// combineReducers 接收的参数是对象
// 所以 initialReducer 的类型是对象
// 作用:将对象中所有的 reducer 组合成一个大的 reducer
const reducers = {};
// applyMiddleware 接收的参数是可变参数
// 所以 middleware 是数组
// 作用:将所有中间件组成一个数组,依次执行
const middleware = [];
const store = createStore(
combineReducers(reducers),
initial_state, // 设置 state 的初始值
applyMiddleware(...middleware)
);
```
--------------------------------
### Install dva-immer
Source: https://github.com/dvajs/dva/blob/master/packages/dva-immer/README.md
Installs the dva-immer package using npm.
```bash
$ npm install dva-immer --save
```
--------------------------------
### Install dva-loading
Source: https://github.com/dvajs/dva/blob/master/packages/dva-loading/README.md
Installs the dva-loading package using npm. This is the first step to integrate the plugin into your dva project.
```bash
$ npm install dva-loading --save
```
--------------------------------
### Dva Plugin Registration and Usage
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Explains how to use the `app.use()` method to register plugins or configure hooks. It provides an example of integrating the `dva-loading` plugin.
```APIDOC
app.use(hooks)
Registers hooks or plugins.
hooks: An object containing hook configurations.
Example with dva-loading:
```js
import createLoading from 'dva-loading';
...
app.use(createLoading(opts));
```
```
--------------------------------
### Using Dva with Umi
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Explains how to use Dva within the Umi framework. It involves installing `dva-cli@next` and then following similar steps as creating a standalone Dva project to create and run a Umi project with Dva integration.
```bash
$ npm install dva-cli@next -g
$ dva new myapp
$ cd myapp
$ npm start
```
--------------------------------
### Dva Store Enhancer Example (Redux-Persist)
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Demonstrates how to apply extra StoreEnhancers using `extraEnhancers`, such as integrating `redux-persist` for state persistence.
```javascript
import { persistStore, autoRehydrate } from 'redux-persist';
const app = dva({
extraEnhancers: [autoRehydrate()],
});
persistStore(app._store);
```
--------------------------------
### Dva Redux Logger Middleware Example
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Demonstrates how to integrate the `redux-logger` middleware using the `onAction` hook for logging dispatched actions.
```javascript
import createLogger from 'redux-logger';
const app = dva({
onAction: createLogger(opts),
});
```
--------------------------------
### Dva Extra Reducers Example (Redux-Form)
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Illustrates how to provide additional reducers to Dva using `extraReducers`, such as integrating `redux-form`'s reducer.
```javascript
import { reducer as formReducer } from 'redux-form'
const app = dva({
extraReducers: {
form: formReducer,
},
});
```
--------------------------------
### Store Subscription and Saga Execution
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
Illustrates how the Dva store is extended with methods like `runSaga` and how listeners for state changes are registered. It also shows the execution of sagas and the setup for running model subscriptions.
```js
// Extend store
store.runSaga = sagaMiddleware.run;
store.asyncReducers = {};
// Execute listeners when state is changed
const listeners = plugin.get('onStateChange');
for (const listener of listeners) {
store.subscribe(() => {
listener(store.getState());
});
}
// Run sagas
sagas.forEach(sagaMiddleware.run);
```
--------------------------------
### Asynchronous Requests with Fetch
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Shows how to make asynchronous GET and POST requests using the `request` utility, which is based on whatwg-fetch. It illustrates basic request patterns and how to include request bodies.
```javascript
import request from '../util/request';
// GET
request('/api/todos');
// POST
request('/api/todos', {
method: 'POST',
body: JSON.stringify({ a: 1 }),
});
```
--------------------------------
### Page Navigation with Router Redux
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Provides examples of how to perform page navigation using `dva/router`. It demonstrates using `routerRedux.push` within effects and outside effects, including how to pass query parameters.
```javascript
import { routerRedux } from 'dva/router';
// Inside Effects
yield put(routerRedux.push('/logout'));
// Outside Effects
dispatch(routerRedux.push('/logout'));
// With query
routerRedux.push({
pathname: '/logout',
query: {
page: 2,
},
});
```
--------------------------------
### DvaJS App Start with React-Redux Provider
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
Demonstrates how DvaJS initializes its store and uses React-Redux's Provider to render the application. It covers handling the container element, exporting the provider for HMR, and rendering the React component.
```js
if (isString(container)) {
container = document.querySelector(container);
invariant(
container,
`[app.start] container ${container} not found`,
);
}
// Other code
// Instantiate store
oldAppStart.call(app);
const store = app._store;
// export _getProvider for HMR
// ref: https://github.com/dvajs/dva/issues/469
app._getProvider = getProvider.bind(null, store, app);
// If has container, render; else, return react component
// If there is a real dom object, render the react component into it
if (container) {
render(container, store, app, app._router);
// Hot loading is here
app._plugin.apply('onHmr')(render.bind(null, container, store, app));
} else {
// Otherwise, generate a react component for external calls
return getProvider(store, this, this._router);
}
// Wrap the component with a higher-order component
function getProvider(store, app, router) {
return extraProps => (
{ router({ app, history: app._history, ...extraProps }) }
);
}
// The actual react rendering happens here
function render(container, store, app, router) {
const ReactDOM = require('react-dom/client') // eslint-disable-line
ReactDOM.createRoot(container).render(React.createElement(getProvider(store, app, router)));
}
```
--------------------------------
### Dva Router Configuration
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Illustrates how to configure the application's routing using `app.router()`. It covers standard React Router setup and the use of a separate router configuration file for HMR.
```APIDOC
app.router(({ history, app }) => RouterConfig)
Registers the route configuration.
Standard usage:
```js
import { Router, Route } from 'dva/router';
app.router(({ history }) => {
return (
);
});
```
Using a separate router file for HMR:
```js
app.router(require('./router'));
```
For multi-page applications without routing:
```js
app.router(() => );
```
```
--------------------------------
### Dva Component Example
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
A stateless React functional component for a Dva application. It displays the highest record and current count from the 'count' model and includes a button to dispatch an 'add' action.
```jsx
import styles from './index.less';
const CountApp = ({count, dispatch}) => {
return (
Highest Record: {count.record}
{count.current}
);
};
```
--------------------------------
### Dva API - `app.start()`
Source: https://github.com/dvajs/dva/blob/master/README.md
The `app.start()` method mounts the Dva application to a specified DOM element. It typically takes a CSS selector string as an argument, indicating where the root component should be rendered.
```APIDOC
app.start(container)
- Mounts the Dva application to the DOM.
- Parameters:
- container: A string CSS selector or a DOM element where the application will be mounted.
Example:
app.start('#root'); // Mounts the app to the element with id 'root'
```
--------------------------------
### Define Dva Model
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Defines a Dva model with a namespace and initial state. The 'count' namespace holds 'record' and 'current' states, representing highest record and current click speed, respectively.
```javascript
app.model({
namespace: 'count',
state: {
record : 0,
current: 0,
},
});
```
--------------------------------
### DvaJS Data Binding with React Redux
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
Illustrates how to connect a React component to the DvaJS model's state using `react-redux`. The `mapStateToProps` function maps the state from the DvaJS store to the component's props, and `connect` HOC integrates it.
```javascript
function mapStateToProps(state) {
return { count: state.count };
}
const HomePage = connect(mapStateToProps)(CountApp);
```
--------------------------------
### DvaJS Component Integration
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This snippet shows how a React component is connected to the DvaJS model. The `connect` function from `dva/router` is used to map the state of the 'count' model to the component's props. The component then uses these props to display the current and highest record values and dispatches actions to the model via the `dispatch` prop.
```javascript
import styles from './index.less';
const CountApp = ({count, dispatch}) => {
return (
Highest Record: {count.record}
{count.current}
);
};
function mapStateToProps(state) {
return { count: state.count };
}
const HomePage = connect(mapStateToProps)(CountApp);
```
--------------------------------
### DvaJS Async Effect: Add then Minus
Source: https://github.com/dvajs/dva/blob/master/docs/GettingStarted.md
This snippet demonstrates how to define an asynchronous effect in DvaJS. The `addThenMinus` effect first dispatches an 'add' action, waits for 1 second using `call(delay, 1000)`, and then dispatches a 'minus' action. This showcases handling side effects with `redux-saga`'s `call` and `put`.
```javascript
app.model({
namespace: 'count',
effects: {
*addThenMinus(action, { call, put }) {
yield put({ type: 'add' });
yield call(delay, 1000);
yield put({ type: 'minus' });
},
},
});
function delay(timeout){
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
```
--------------------------------
### Dva Application Creation and Configuration
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Shows how to create a Dva application instance with various configuration options, including history management and initial state. It also details how to integrate custom hooks and enhancers.
```APIDOC
app = dva(opts)
Creates an application instance.
opts:
history: Specifies the history object for routing (defaults to hashHistory).
initialState: Sets the initial state for the application (defaults to {}).
onError((err, dispatch) => {}): Callback for handling errors in effects or subscriptions.
onAction(fn | fn[]): Registers Redux middleware.
onStateChange(fn): Callback when the state changes.
onReducer(fn): Wraps the reducer execution.
onEffect(fn): Wraps the effect execution.
onHmr(fn): Handles Hot Module Replacement.
extraReducers: Specifies additional reducers.
extraEnhancers: Specifies additional StoreEnhancers.
Example with browserHistory:
```js
import createHistory from 'history/createBrowserHistory';
const app = dva({
history: createHistory(),
});
```
Example with all hooks:
```js
const app = dva({
history,
initialState,
onError,
onAction,
onStateChange,
onReducer,
onEffect,
onHmr,
extraReducers,
extraEnhancers,
});
```
```
--------------------------------
### Dva API - `dva()`
Source: https://github.com/dvajs/dva/blob/master/README.md
The `dva()` function initializes the Dva application. It can be configured with options such as `history` for routing and `plugins` for extending functionality. This is the entry point for creating a Dva application.
```APIDOC
dva(options?)
- Initializes and returns a Dva app instance.
- Options:
- history: Browser history object (e.g., createBrowserHistory from history).
- initialState: Initial state for the Redux store.
- plugins: An array of Dva plugins.
- onError: Callback function for handling errors.
- onAction: Middleware for Redux actions.
- onStateChange: Callback when state changes.
- onReducer: Enhancer for reducers.
- onEffect: Enhancer for effects.
- extraReducers: Additional reducers to merge.
- models: An array of models to register initially.
Example:
import createHistory from 'history/createBrowserHistory';
import dva from 'dva';
const app = dva({
history: createHistory(),
// ... other options
});
// Register models and start the app
app.model(require('./models/example'));
app.router(require('./router'));
app.start('#root');
```
--------------------------------
### Reducer Example (FP)
Source: https://github.com/dvajs/dva/blob/master/docs/Concepts.md
Provides a functional programming example of a reducer using `Array.prototype.reduce` to merge objects, illustrating the concept of accumulating state.
```javascript
[{x:1},{y:2},{z:3}].reduce(function(prev, next){
return Object.assign({}, prev, next);
})
```
--------------------------------
### Dynamic Component Loading with Dva
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Demonstrates how to dynamically load components and their associated models using Dva's `dynamic` utility. This is useful for code splitting and improving initial load times.
```javascript
import dynamic from 'dva/dynamic';
const UserPageComponent = dynamic({
app,
models: () => [
import('./models/users'),
],
component: () => import('./routes/UserPage'),
});
```
--------------------------------
### Dva Error Handling Example
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Provides an example of implementing global error handling using the `onError` hook, specifically showing how to display an error message using Ant Design's `message` component.
```javascript
import { message } from 'antd';
const app = dva({
onError(e) {
message.error(e.message, /* duration */3);
},
});
```
--------------------------------
### Dva Reducer for Nested State
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Provides examples of handling nested state updates within Dva.js reducers. It recommends keeping state flat for maintainability and shows an example of updating nested data, advising against deep nesting.
```APIDOC
app.model({
namespace: 'app',
state: {
todos: [],
loading: false,
},
reducers: {
add(state, { payload: todo }) {
const todos = state.todos.concat(todo);
return { ...state, todos };
},
},
});
// Avoid deep nesting like this:
app.model({
namespace: 'app',
state: {
a: {
b: {
todos: [],
loading: false,
},
},
},
reducers: {
add(state, { payload: todo }) {
const todos = state.a.b.todos.concat(todo);
const b = { ...state.a.b, todos };
const a = { ...state.a, b };
return { ...state, a };
},
},
});
```
--------------------------------
### DvaJS Saga Middleware Initialization
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
Demonstrates the initialization of the saga middleware in DvaJS and how it's integrated with the store. It shows the process of collecting sagas from models and running them.
```javascript
const sagaMiddleware = createSagaMiddleware();
// ...
const sagas = [];
const reducers = {...initialReducer};
for (const m of app._models) {
reducers[m.namespace] = getReducer(m.reducers, m.state);
if (m.effects) sagas.push(app._getSaga(m.effects, m, onError, plugin.get('onEffect')));
}
// ....
store.runSaga = sagaMiddleware.run;
// Run sagas
sagas.forEach(sagaMiddleware.run);
```
--------------------------------
### createStore Simplified Example
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
A simplified representation of the `createStore` function in Dva.js, showing the core Redux store creation process. It applies middlewares (like saga and promise middleware) and enhancers, then creates the Redux store with the combined reducers and initial state.
```js
import { createStore, applyMiddleware, compose } from 'redux';
import flatten from 'flatten';
import invariant from 'invariant';
import window from 'global/window';
import { returnSelf, isArray } from './utils';
export default function ({ /* ... options */ }) {
const middlewares = setupMiddlewares([
sagaMiddleware,
promiseMiddleware
]);
const enhancers = [
applyMiddleware(...middlewares)
];
return createStore(reducers, initialState, compose(...enhancers));
}
```
--------------------------------
### JSX Comments
Source: https://github.com/dvajs/dva/blob/master/docs/knowledgemap/README.md
Provides examples of single-line and multi-line comments within JSX using curly braces and double slashes.
```javascript
{/* multiline comment */}
{/*
multi
line
comment
*/}
{
// single line
}
Hello
```
--------------------------------
### Plugin System and Hooks
Source: https://github.com/dvajs/dva/blob/master/docs/guide/source-code-explore.md
Illustrates the `Plugin` class and its `use` method for managing hooks. It shows how hooks are filtered and added to the plugin's internal state, and how the `apply` method is used to execute these hooks.
```javascript
const hooks = [
'onError',
'onStateChange',
'onAction',
'onHmr',
'onReducer',
'onEffect',
'extraReducers',
'extraEnhancers',
];
export function filterHooks(obj) {
return Object.keys(obj).reduce((memo, key) => {
// 如果对象的 key 在 hooks 数组中
// 为 memo 对象添加新的 key,值为 obj 对应 key 的值
if (hooks.indexOf(key) > -1) {
memo[key] = obj[key];
}
return memo;
}, {});
}
export default class Plugin {
constructor() {
this.hooks = hooks.reduce((memo, key) => {
memo[key] = [];
return memo;
}, {});
/*
等同于
this.hooks = {
onError: [],
onStateChange:[],
....
extraEnhancers: []
}
*/
}
use(plugin) {
invariant(isPlainObject(plugin), 'plugin.use: plugin should be plain object');
const hooks = this.hooks;
for (const key in plugin) {
if (Object.prototype.hasOwnProperty.call(plugin, key)) {
invariant(hooks[key], `plugin.use: unknown plugin property: ${key}`);
if (key === 'extraEnhancers') {
hooks[key] = plugin[key];
} else {
hooks[key].push(plugin[key]);
}
}
}
}
apply(key, defaultHandler) {
const hooks = this.hooks;
/* 通过 validApplyHooks 进行过滤, apply 方法只能应用在全局报错或者热更替上 */
const validApplyHooks = ['onError', 'onHmr'];
invariant(validApplyHooks.indexOf(key) > -1, `plugin.apply: hook ${key} cannot be applied`);
/* 从钩子中拿出挂载的回调函数 ,挂载动作见 use 部分*/
const fns = hooks[key];
return (...args) => {
// 如果有回调执行回调
if (fns.length) {
for (const fn of fns) {
fn(...args);
}
// 没有回调直接抛出错误
} else if (defaultHandler) {
defaultHandler(...args);
/*
这里 defaultHandler 为 (err) => {
throw new Error(err.stack || err);
}
*/
}
};
}
// 其他方法
}
```
--------------------------------
### State Initialization with initialState
Source: https://github.com/dvajs/dva/blob/master/docs/api/README.md
Demonstrates how to initialize the Dva application state using the `initialState` option when creating the app instance. This initial state takes precedence over the `state` defined within a model if the namespace matches.
```js
const app = dva({
initialState: { count: 1 },
});
app.model({
namespace: 'count',
state: 0,
});
// After app.start(), state.count will be 1.
```
--------------------------------
### dva API - `app.use()`
Source: https://github.com/dvajs/dva/blob/master/README_zh-CN.md
The `app.use()` method registers plugins with the dva application. Plugins can extend dva's functionality, such as handling loading states (`dva-loading`) or adding custom middleware.
```APIDOC
app.use(plugin)
Parameters:
plugin: Object (required) - A plugin object, typically with `onEffect`, `onAction`, `onStateChange`, etc. methods.
Returns:
Object - The dva app instance for chaining.
Example Usage with dva-loading:
import createLoading from 'dva-loading';
const app = dva();
app.use(createLoading());
app.model({
namespace: 'users',
state: { list: [] },
effects: {
*fetch({ payload }, { call, put }) {
const data = yield call(api.fetchUsers);
yield put({ type: 'save', payload: data });
},
},
reducers: {
save(state, action) {
return { ...state, ...action.payload };
},
},
});
app.start('#root');
```
--------------------------------
### Reducer Example
Source: https://github.com/dvajs/dva/blob/master/docs/guide/concepts.md
Illustrates the concept of a reducer function, which takes previous state and an action to return new state. Reducers must be pure functions.
```javascript
[{x:1},{y:2},{z:3}].reduce(function(prev, next){
return Object.assign(prev, next);
})
```