这个问题有人回答么,我也遇到了类似的问题,翻了好几个地方的文档,都没有解决问题。我在reducer中return了新的数据,route层在render里打印出了数据,但是是明显没有更新的
@Gaven-Xu 你在render中打印了就一定会更新,可以发代码。我的问题和你还不一样 不只是显示问题。我是想把服务端的返回码在form表单中以自定义错误提示的方式在某个field显示出来
窝在render里面打印的是没有更新的数据,很奇怪,不知道是不是漏写了什么,模仿官方demo写的,应该没有漏掉什么,@connect也写了
我的route:
`import React, { Component } from "react";
import { connect } from "dva";
import { Form, Icon, Input, Button, Row, Col, Table } from "antd";
import styles from "./AgentManage.less";
const FormItem = Form.Item;
@connect(state => ({
angetdata:state.angetdata
}))
export default class AgentManage extends Component {
state={
angetdata:[{
key: '1',
name: '胡',
age: 32,
address: '西湖'
}, {
key: '2',
name: '祖',
age: 42,
address: '西湖'
}]
}
componentDidMount() {
// To disabled submit button at the beginning.
// TODO: 暂时没用
// this.props.form.validateFields();
this.props.dispatch({
type: "agent/fetch",
payload:this.state
});
}
shouldComponentUpdate= true;
render() {
const columns = [{
title: '姓名',
dataIndex: 'name',
key: 'name',
}, {
title: '年龄',
dataIndex: 'age',
key: 'age',
}, {
title: '住址',
dataIndex: 'address',
key: 'address',
}];
console.log(this.state)
return (
<div>
<Row>
<Col>
<Table dataSource={this.state.angetdata} columns={columns}/>
</Col>
</Row>
</div>
);
}
}
我的model:
import { queryAgent } from "../services/agent";
export default {
namespace: "agent",
state: {
angetdata: [],
loading: false
},
effects: {
*fetch({ payload }, { call, put }) {
console.log("this m is from modal agent.js");
yield put({
type: "changeLoading",
payload: true
});
// const response = yield call(queryAgent, payload);
const response = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}];
yield put({
type: "returnAgentData",
payload: Array.isArray(response) ? response : [],
});
yield put({
type: "changeLoading",
payload: false
});
}
},
reducers: {
returnAgentData(state, action) {
// console.log('state',state,'action',action)
console.log('reducers已经执行:'+typeof action.payload, action.payload)
return {
...state,
angetdata: action.payload
};
},
changeLoading(state, action) {
return {
...state,
loading: action.payload
};
},
},
};
`
@Gaven-Xu render 中取值的时候不要直接this.state, 试试 const {agent:{angetdata}} = this.props
我试过,我的state下直接是angetdata,所以应该是const {angetdata} = this.props吧,我打印了props,angetdata字段是有的,但是值为undefined
@becky-guo 你的问题我考虑可以这么解决,其实你这是一个表单异步校验的需求。ant-design官方对于异步校验好像并没有给出实践。但是可以利用 ant-design 自定义校验的机制自己进行异步校验,代码如下:
import request from 'path-to-dva-request';
asyncCheck = (rule, value, callback) => {
request('path/to/valid/email', {
method: 'post',
body: emialValue
}).then(({data})=> {
if(data.code == 1) {
callback('邮箱已经存在');
}else {
callback();
}
})
}
在 ant-design 的 自定义校验中,如果 callback 方法不调用,验证会一直处于阻塞状态。这种异步验证表单的问题不需要通过 redux store 来托管数据,这样反而会丢失数据获取到的时间,导致需要在 componentWillReceiveProps 中去通过其他 ‘脏’ 手段触发表单验证。
@yvanwangl 是的 我纠结的也就是如何很好的利用model托管,真正的做到视图与数据分离。
@yvanwangl 感谢提供的思路,不然掉坑里了 哈哈
@becky-guo 客气,问题解决了就把它关了吧 : )
@yvanwangl @sorrycc 服务端接口返回的数据格式{code:0,msg:"xxxx"} ,在model effect处理不同code的情况,给页面相应的提示是频繁的操作, 如果这个没法处理,全部在页面写request,那model是不是没有意义了,朋友们给点建议
@becky-guo 我个人感觉,dva model 的作用是对 redux reducer 的一种切片处理,方便你不同领域模型的数据分开,就你上面的那个需求而言是一个数据的临时验证逻辑,并不需要redux store去维护你的状态,因为你输入不同的邮箱可能会返回不同的 code,是一种‘瞬时’性的数据,所以不用 redux store 去存储。
model 是 dva 的核心, 你可以认为是一个调度器,model 中的 state 是 redux reducer 的 initialState, effects 会调度给 saga 处理,reducers 会直接调度给 redux 处理,同时还给了一个 subscriptions 钩子注册功能,让你可以监听例如路由这样的事件,model 存在的意义并不是 '持久' 数据的,这个是底层 redux 的作用。以上仅代表个人理解。
@yvanwangl 悟了!我之前执着于一定要把api请求放在model里,其实可以在routes里请求,做状态判断,然后再把需要更新的结果dispatch到model中,通过reducer去更新这样就完美了。就是把你说的”瞬时“数据和”持久“数据在view分隔开来处理。感谢!
@becky-guo 可以放在 routes 里请求,并不代表应该放在 routes 里,放 model 里处理的好处是你所有的行为可以集中管理,包括异步的和同步的。
Most helpful comment
@becky-guo 可以放在 routes 里请求,并不代表应该放在 routes 里,放 model 里处理的好处是你所有的行为可以集中管理,包括异步的和同步的。