You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
6.8 KiB

---
order: 3
title: Practical Projects
---
[dva](https://github.com/dvajs/dva) is a React and redux based, lightweight and elm-style framework, which supports side effects, hot module replacement, dynamic on demand, react-native, SSR. And it has been widely used in production environment.
This article will guide you to create a simple application from zero using dva and antd.
Include the following:
---
## Install dva
Install dva with npm.
```bash
$ npm install dva-cli -g
```
## Create New App
After installed dva-cli, you can have access to the `dva` command in terminal. Now, create a new application with `dva new`.
```bash
$ dva new dva-quickstart
```
This creates `dva-quickstart` directory, that contains the project directories and files, and provides development server, build script, mock service, proxy server and so on.
Then `cd` the `dva-quickstart` directory, and start the development server.
```bash
$ cd dva-quickstart
$ npm start
```
8 years ago
After a few seconds, you will see the following output:
```bash
proxy: load rule from proxy.config.js
proxy: listened on 8989
📦 411/411 build modules
webpack: bundle build is now finished.
```
Open http://localhost:8989 in your browser, you will see dva welcome page.
## Integrate antd
8 years ago
Install `antd` and `babel-plugin-import` with npm. `babel-plugin-import` is used to automatically import scripts and stylesheets from antd in demand. See [repo](https://github.com/ant-design/babel-plugin-import) 。
```bash
$ npm install antd babel-plugin-import --save
```
Edit `webpack.config.js` to integrate `babel-plugin-import`.
```diff
+ webpackConfig.babel.plugins.push(['import', {
+ libraryName: 'antd',
+ style: 'css',
+ }]);
```
> Notice: No need to manually restart the server, it will restart automatically after you save the `webpack.config.js`.
## Define Router
We need to write an application displaying the list of products. The first step is to create a route.
Create a route component `routes/Products.js`:
```javascript
import React from 'react';
8 years ago
const Products = (props) => (
<h2>List of Products</h2>
);
8 years ago
export default Products;
```
8 years ago
Add routing information to router, edit `router.js`:
```diff
+ import Products from './routes/Products';
...
+ <Route path="/products" component={Products} />
```
Then open http://localhost:8989/#/products in your browser, you should be able to see the `<h2>` tag defined before.
## Write UI Components
As your application grows and you notice you are sharing UI elements between multiple pages (or using them multiple times on the same page), in dva it's called reusable components.
Let's create a `ProductList` component that we can use in multiple places to show a list of products.
Create `components/ProductList.js` and typing:
```javascript
import React, { PropTypes } from 'react';
import { Table, Popconfirm, Button } from 'antd';
const ProductList = ({ onDelete, products }) => {
8 years ago
const columns = [{
title: 'Name',
dataIndex: 'name',
}, {
title: 'Actions',
render: (text, record) => {
return (
<Popconfirm title="Delete?" onConfirm={() => onDelete(record.id)}>
<Button>Delete</Button>
</Popconfirm>
);
},
8 years ago
}];
return (
<Table
dataSource={products}
columns={columns}
/>
);
};
ProductList.proptypes = {
onDelete: PropTypes.func.isRequired,
products: PropTypes.array.isRequired,
};
export default ProductList;
```
## Define Model
After complete the UI, we will begin processing the data and logic.
dva manages domain model with `model`, with reducers for synchronous state update, effects for async logic, and subscriptions for data source subscribe.
Let's create a model `models/products.js` and typing:
```javascript
import dva from 'dva';
export default {
namespace: 'products',
state: [],
reducers: {
'delete'(state, { payload: id }) {
return state.filter(item => item.id !== id);
},
},
};
```
In this model:
- `namespace` represent the key on global state
- `state` is the initial value, here is an empty array
- `reducers` is equal to reducer in redux, accepting action, and update state synchronously
Then don't forget to require it in `index.js`:
```diff