一、问题描述:
点击同一页面不同数据跳转到该数据的详情页面时,路由变化但页面停留在第一次点击的数据详情页面,除非每次点击后关闭该详情页面,再点击下一个数据。
二、发生原因:
当第一次点击数据路由跳转后的详情页面未关闭时,再点击另一个数据执行路由跳转第二次传入的参数Id,虽然路由变化,但此时并未识别为一个新的页面,props中数据只有history的路由相关信息发生改变,此时并未重新执行React的生命周期,因此compontentDidMount中的dispath请求并未发出,因此数据未更新。
三、解决方法:
使用dva的订阅。在dva中我们可以在 Model 中实现事件监听, model 中的 subscriptions 相当于一个监听器,可以监听路由变化,鼠标,键盘变化,服务器连接变化,状态变化等,这样在其中就可以根据不同的变化做出相应的处理,在这个 subsriptions 中的方法名是随意定的,每次变化都会一次去调用里面的所有方法,所以一般会加相应的判断。
四、代码对比:
修改前:
import * as HomeworkManagementService from "@/services/HomeworkManagementService";
export default {
namespace: 'HomeworkManagementModel',
state: {
homeworkData:{list:[],pagination:{}},
pagination: {
total: 0,
current: 1,
pageSize: 10,
},
},
effects: {
* fetch({payload}, {call, put}) {
const path = window.location.pathname;
const reg = /\/HomeworkDetail\/(\d+)/;
const classResult = reg.exec(path);
const courseId = classResult[1];
payload.courseId=courseId;
const response = yield call(HomeworkManagementService.getAllHomework, payload);
const {data: { records, current, size, total }} = response;
const list =records;
const pagination = {
current: current || 1,
pageSize:size,
total,
};
const result = {
list,
pagination,
};
yield put({
type: 'save',
payload: {
homeworkData:result,
pagination
}
})
},
},
reducers: {
save(state, {payload}) {
return (
{
...state,
...payload,
}
)
},
},
};
修改后:
import * as HomeworkManagementService from "@/services/HomeworkManagementService";
export default {
namespace: 'HomeworkManagementModel',
state: {
homeworkData:{list:[],pagination:{}},
pagination: {
total: 0,
current: 1,
pageSize: 10,
},
currentCourseId:"",
},
subscriptions: {
setupHistory({dispatch, history}) {
history.listen((location) => {
const {pathname} = location;
const reg = /\/HomeworkDetail\/(\d+)/;
if (reg.test(pathname)) {
const courseId = reg.exec(pathname)[1];
dispatch({
type: 'save',
payload: {
currentCourseId:courseId,
},
})
// 保存当前页面的id后 调用fetch时也传入当前的id 避免修改后不刷新
dispatch({
type:'fetch',
payload:{
current: 1,
pageSize: 10,
courseId,
}
})
}
})
}
},
effects: {
* fetch({payload}, {call, put,select}) {
const courseId =yield select(state => state.HomeworkManagementModel.currentCourseId);
payload.courseId=courseId;
const response = yield call(HomeworkManagementService.getAllHomework, payload);
const {data: { records, current, size, total }} = response;
const list =records;
const pagination = {
current: current || 1,
pageSize:size,
total,
};
const result = {
list,
pagination,
};
console.log(result)
yield put({
type: 'save',
payload: {
homeworkData:result,
pagination
}
})
},
},
reducers: {
save(state, {payload}) {
return (
{
...state,
...payload,
}
)
},
},
};