我的组件状态没有使用Reducer进行更新,在mapStateToProps中得到的Reducer State很好并且出现在props中但是它不应该更新我的Component的状态以便重新渲染吗?在Reducer中返回状态
来自文档和注释的Spread语法的{...state, rows:news_formated.slice(0,30)}
都说这是用于返回状态的新实例而不是改变状态本身的方法之一。下面是Action,Reducer和部分代码的代码。
class CreateGenericTable extends Component {
constructor(props){
super(props);
this.state = { rows:null, columns:null};
}
componentDidMount(){
var token = getCookie('admin_session_token');
servicerequest = this.props.serviceRequest;
this.setState({columns: this.props.columns})
var teste = this.props.tableList(this.props.editform,this.props.service,token,servicerequest,this.props.columns)
console.log(this.props);
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({ tableList, editComponent }, dispatch);
}
const mapStateToProps = (state,ownProps) => {
console.log('this is state');
//console.log(state);
if(state.tabledata.rows!=null){
debugger;
return { rows: state.tabledata.rows};
}else{
return { rows: null};
}
};
//export default connect(null, mapDispatchToProps)(CreateGenericTable)
const CreateGenericTableRedux = connect(mapStateToProps, mapDispatchToProps)(CreateGenericTable)
动作
import $ from "jquery";//https://redux.js.org/docs/advanced/AsyncActions.html Asynchronous calls need to use thunk of redux.....
//import { connect } from 'react-redux';
export const FETCH_TABLEDATA = 'FETCH_TABLEDATA'
export const EDIT_COMP = 'EDIT_COMP'
export function editComponent(id,View){
return {
type: EDIT_COMP,
payload: {'id':id,'View':View}
}
}
export function tableList(editform,service,token,serviceRequest){
var request = null;
return dispatch => {
$.ajax({
type: "POST",
url: service,
crossDomain: true,
dataType: 'jsonp',
xhrFields: {
withCredentials: true
},
data: {
q: JSON.stringify({
[serviceRequest]:{}
}),
admin_session_token:token,
},
success : (data) => {
request = data;
dispatch({
type: FETCH_TABLEDATA,
payload: {editform: editform,request: request, serviceRequest: serviceRequest }
});
},
error: (xhr, status, err) =>{
////console.log('ups somehting went rong:'.err.toString());
},
});
};
/*
return request.then ({
type: FETCH_TABLEDATA,
payload: {request: request, serviceRequest: serviceRequest, columns: columns}
});
*/
}
减速
import { FETCH_TABLEDATA } from '../actions/index.js'
//const INITIAL_STATE = {rows:null, columns:[]} //separate the data proprocessing to a function -> https://gist.github.com/abhiaiyer91/aaf6e325cf7fc5fd5ebc70192a1fa170
export default function(state = [], action){ switch(action.type){ case FETCH_TABLEDATA:
var data = action.payload.request[action.payload.serviceRequest];//var data = data['News_get'];
console.log('----state---'); console.log(state);
if(data.length>0){
var news_formated = [];
var listofkeys = Object.keys(data[0]);
for(var new_unformated of data){
var new_formated = [];
//console.log(new_unformated);
for(var key of listofkeys){
//console.log(key);
if(action.payload.editform.indexOf('EditHeader') !== -1 && key.indexOf('language_items') !== -1){
new_formated['image'] = new_unformated[key][0]['image'];
new_formated['link'] = new_unformated[key][0]['link'];
}else{
if(action.payload.editform.indexOf('EditNotification') !== -1){
if(key.indexOf('params') !== -1){
new_formated[key] = new_unformated[key]['message'];
}else{
new_formated[key] = new_unformated[key];
}
}else{
if(key.indexOf('active') !== -1){
if(new_unformated[key].indexOf('1') !== -1){
new_formated[key] = 'Yes';
}else{
new_formated[key] = 'No';
}
}else{
new_formated[key] = new_unformated[key];
}
}
}
}
news_formated.push(new_formated);
}
return {
...state,
rows:news_formated.slice(0,30)
};
}else{
return {
...state,
rows:null
};
}
//{...state, {rows:null, columns:action.payload.columns}}; default: return {
...state,
rows:null
}; } }
答案 0 :(得分:2)
componentDidMount
函数仅在第一次渲染时被调用,然后组件才会安装,因此在redux存储中的任何进一步更新,反映在组件的道具中都不会在您的实现中设置为状态。您需要在componentWillReceiveProps
函数
另外为了提醒你它的反模式有一个可以直接从道具派生的状态,你应该直接使用道具。
虽然你可以实现你想要的目标
class CreateGenericTable extends Component {
constructor(props){
super(props);
this.state = { rows:null, columns:null};
}
componentDidMount(){
var token = getCookie('admin_session_token');
servicerequest = this.props.serviceRequest;
this.setState({columns: this.props.columns})
var teste = this.props.tableList(this.props.editform,this.props.service,token,servicerequest,this.props.columns)
console.log(this.props);
}
componentWillReceiveProps(nextProps) {
if(nextProps.columns !== this.props.columns) { // You might need to have a deep comparison here if columns is not immutable or a nested obejct. You can use _.isEqual from lodash in that case
this.setState({columns: nextProps.columns})
}
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({ tableList, editComponent }, dispatch);
}
const mapStateToProps = (state,ownProps) => {
console.log('this is state');
//console.log(state);
if(state.tabledata.rows!=null){
debugger;
return { rows: state.tabledata.rows};
}else{
return { rows: null};
}
};
export default connect(null, mapDispatchToProps)(CreateGenericTable)
如果可能,我会严格建议您直接在组件中使用this.props.columns
,而不是将其保持在状态