技術介紹
看了demo寫一個刪除的方法
dva首先是一個基於 redux 和 redux-saga 的數據流方案
dva model : 把數據邏輯從頁面中抽離出來,使用 dispatch 和 reducer 改變 dva model。
dispatch:分發函數方法
reducer:接收數據處理(函數方法)
connect : 對接靜態的 dva model
model.ts
export default {
namespace: 'zhangxiaojuan',
state: {
data: [{
id: 1,
setup: 'Did you hear about the two silk worms in a race?',
punchline: 'It ended in a tie',
},
{
id: 2,
setup: 'What happens to a frog\'s car when it breaks down?',
punchline: 'It gets toad away',
},
],
counter: 2,
},
reducers: {
addNewCard(state, {payload: newCard}) {
const nextCounter = state.counter + 1;
const newCardWithId = {...newCard, id: nextCounter};
const nextData = state.data.concat(newCardWithId);
return {
data: nextData,
counter: nextCounter,
};
},
removeCard(state){
return {
data:state.data.slice(0,state.data.length-1),
counter:--state.counter
}
}
},
};
index.tsx
import React from 'react';
import { Card,Tabs,Tree,Layout,Button } from 'antd';
import { connect } from 'dva';
const namespace = 'zhangxiaojuan';
//數據注入
const mapStateToProps = (state) => {
const cardList = state[namespace].data;
const counter = state[namespace].counter;
return {
cardList,counter,
};
};
//改變數據的方法注入
const mapDispatchToProps = (dispatch) => {
return {
onClickAdd: (newCard) => {
dispatch({
type: `${namespace}/addNewCard`,
payload: newCard,
});
},
removeCard:() => {
dispatch({
type:`${namespace}/removeCard`,
})
}
};
};
@connect(mapStateToProps,mapDispatchToProps)
export default class ProductList extends React.Component{
constructor(props) {
super(props);
this.state = {
expandedKeys: [],
};
}
render() {
return (
<div>
{
this.props.cardList.map(card => {
return (
<Card key={card.id}>
<div>Q: {card.setup}</div>
<div>
<strong>A: {card.punchline}</strong>
</div>
</Card>
);
})
}
<div>
<div>總長度:{this.props.counter}</div>
<Button onClick={() => this.props.onClickAdd({
setup: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
punchline: 'here we use dva',
})}> 添加卡片 </Button>
<Button onClick={()=>this.props.removeCard()}>減少卡片</Button>
</div>
</div>
);
}
componentDidMount() {
}
};
從後臺獲取數據
effects:集中處理http請求
只貼關鍵代碼
1.index.tsx
import React from 'react';
import {Card, Button} from 'antd';
import {connect} from 'dva';
const namespace = 'zhangxiaojuan';
//數據注入
const mapStateToProps = (state) => {
const cardList = state[namespace].data;
const counter = state[namespace].counter;
return {
cardList, counter,
};
};
//改變數據的方法注入
const mapDispatchToProps = (dispatch) => {
return {
onDidMount: () => {
dispatch({
type: `${namespace}/queryInitCards`,
callback: (res: { list:any; }) => {
console.log(res);
if (res) {
dispatch({
type: `${namespace}/cardList`,
payload: res.list,
});
} else {
dispatch({
type: `${namespace}/cardList`,
payload: [],
});
}
}
});
}
};
};
@connect(mapStateToProps, mapDispatchToProps)
export default class ProductList extends React.Component {
render() {
return (
<div>
{
this.props.cardList.map((card,index) => {
return (
<Card key={index}>
<div>Q: {card.memberName}</div>
<div>
<strong>A: {card.date}</strong>
</div>
</Card>
);
})
}
<div>
<div>總長度:{this.props.counter}</div>
</div>
);
}
componentDidMount() {
this.props.onDidMount();
}
};
2.model.tsx
import request from '@/utils/request';
export async function query(params: object) {
return request('/resource/sales/list', {
params,
});
}
export default {
namespace: 'zhangxiaojuan',
state: {
// data: ...
}
reducers: {
cardList(state, {payload: newCard}) {
return {
data: newCard,
counter: newCard.length,
}
}
},
effects: {
* queryInitCards({callback}, {call}) {
const response = yield call(query, {});
if (callback) callback(response);
}
}
}
講解圖,來自其他網站