### 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); }) ```