版权声明:原创不易,如需转载,请注明出处。有梦想地需要你的一个赞(顶)。 https://blog.csdn.net/genius_yym/article/details/80696693
React 声明组件后数据没有动态发生变化的解决思路之一
问题描述
组件声明了之后,发现,组件只会在初始的时候向后台发送请求数据,当后面再通过componentWillReceiveProps
的改变去触发请求api的时候,发现,其不会触发。也就是说,数据只会在第一次加载组件的触发了仅此一次的api请求。
解决思路
通过 action
来声明方法,reducer
存取数据,从而使得能在componentWillReceiveProps
控制数据的变化。
示例
(一)存在问题的代码
import React from 'react';
import { Row, Col, Select } from 'antd';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Api from '../../apps/api';
const Option = Select.Option;
const DictCacher = {};
export default class BigProjSelect extends React.Component {
constructor() {
super();
this.state = {
dictItemList: []
}
}
componentDidMount() {
const params = { userid: this.props.userid, projid: this.props.projid };
const _this = this;
Api.getProjAuthDataByUserAndProjid(params).then(({ jsonResult = { data: [] } }) => {
DictCacher[params.groupId] = jsonResult.data;
_this.setState({ dictItemList: jsonResult.data });
})
}
componentWillReceiveProps(nextProps) {
const _this = this;
if (nextProps.ProTreSelected!==this.props.ProTreSelected) {
const params = {
userid: nextProps.userInfo.user.userid,
projid: nextProps.ProTreSelected
}
//直接在组件中请求数据
Api.getProjAuthDataByUserAndProjid(params).then(({ jsonResult = { data: [] } }) => {
DictCacher[params.groupId] = jsonResult.data;
_this.setState({ dictItemList: jsonResult.data });
})
}
}
render() {
const loop = data => data.map((item) => {
return <Option key={item} value={item}>{item}</Option>;
});
return (
<Select {...this.props} size="large" allowClear>
{/* 获取state 数据*/}
{loop(this.state.dictItemList.authorises)}
</Select>
)
}
}
(二)优化后的代码
import React from 'react';
import { Row, Col, Select, Form } from 'antd';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
// 引入对应的action
import * as action from '../../apps/action';
const Option = Select.Option;
const DictCacher = {};
class BigProjSelect extends React.Component {
constructor() {
super();
this.state = {
dictItemList: []
}
}
componentDidMount() {
// getProjAuthDataByUserAndProjid 是声明的方法
this.props.getProjAuthDataByUserAndProjid({ userid: this.props.userInfo.user.userid, projid: this.props.ProTreSelected })
}
componentWillReceiveProps(nextProps) {
if (nextProps.ProTreSelected!==this.props.ProTreSelected) {
// 调用action的方法
this.props.getProjAuthDataByUserAndProjid({userid: nextProps.userInfo.user.userid, projid: nextProps.ProTreSelected})
}
}
render() {
const loop = data => data.map((item) => {
return <Option key={item.projid} value={item.projid}>{item.projname}</Option>;
});
return (
<Select
size="large"
{...this.props}
allowClear={false}
onSelect={::this.changeSelect}
>
{/* 获取reducer 数据*/}
{loop(this.props.bigprojData)}
</Select>
)
}
}
function mapStateToProps(state, ownProps) {
return {
userInfo: state.getIn(['APP', 'userInfo']),
ProTreSelected: state.getIn(['APP', 'ProTreSelected']),
// 获取reducer数据
bigprojData: state.getIn(['APP', 'bigprojData']),
}
}
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators(action, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(BigProjSelect)
总结
前者是 直接在组件内,通过Api
去请求后台数据,随之通过sate
的存取来运用数据。
后者是 把该方法在action
中声明,然后在页面中调用,而数据则是通过reducer
传进来。
最后,这是一个笔记。另,关于mapStateToProps
和mapDispatchToProps
可以参看文章:React依赖注入说明(mapStateToProps/mapDispatchToProps)