对于我正在编写的反应组件,我正在使用redux来管理组件的状态。我之前没有真正使用过redux,所以我遇到了一些我写过的reducer的问题。我的react组件中的一个方法使http请求然后通过一个简单的动作函数将数据分派到reducer。但是,我为此reducer编写了另一个操作来删除状态中的条目,但每当我使用此操作时,reducer返回一个空数组。任何帮助表示赞赏。
减速器:
export function Weeklystate(state=[], action){
switch(action.type){
case 'ADD_PROVIDER':
return [...state, action.arr];
case 'REMOVE_PROVIDER':
const newstate = [...state];
return newstate.filter((provider) => provider[0].full_name.toLowerCase().indexOf(action.str) === -1);
default:
return state;
}
}
actions.js :
export function addProvider(arr){
return {
type: 'ADD_PROVIDER',
arr
};
}
export function removeProvider(str){
return {
type: 'REMOVE_PROVIDER',
str
};
}
组件方法:
getData(){
const { url, queries } = this.state;
let data_arr = [];
const que = queries.map(function(query){
let postquery = {
full_name: query.name,
date_start: query.startdate,
date_end: query.enddate
};
return axios.post(url, postquery);
});
axios.all(que).then((responses) => {
responses.forEach((response) => {
this.props.addProvider(response.data);
});
});
}
componentWillMount(){
this.getData();
this.props.removeProvider('Example Name here');
const { rawdata } = this.props;
return console.log(this.props);
}
MaptoProps功能:
function mapStateToPropsBETA(state){
return {
rawdata: state.rawdata,
parseddata: state.parseddata
};
}
function mapDispatchtoProps(dispatch){
return bindActionCreators({
addProvider: addProvider,
removeProvider: removeProvider
}, dispatch);
}
export default connect(mapStateToPropsBETA, mapDispatchtoProps)(Weekly_Beta);
stores.js :
const WeeklyStore = createStore(reducer);
WeeklyStore.subscribe(() => {
console.log(WeeklyStore.getState());
});
export default WeeklyStore;
示例数据:
[
[
{
first_name: "First Name Here...",
last_name: "Last Name Here...",
full_name: "Full Name Here",
date: "2016-01-17",
charges: {
cosmetic: 25000.00,
medical: 25000.00,
total: 50000.00
},
payments: 75000.00,
appointments: 99,
pk: 5
},
{
first_name: "First Name Here...",
last_name: "Last Name Here...",
full_name: "Full Name Here",
date: "2016-01-24",
charges: {
cosmetic: 25000.00,
medical: 25000.00,
total: 50000.00
},
payments: 75000.00,
appointments: 99,
pk: 5
},
],
[
{
first_name: "First Name Here...",
last_name: "Last Name Here...",
full_name: "Full Name Here",
date: "2016-01-17",
charges: {
cosmetic: 25000.00,
medical: 25000.00,
total: 50000.00
},
payments: 75000.00,
appointments: 99,
pk: 5
},
{
first_name: "First Name Here...",
last_name: "Last Name Here...",
full_name: "Full Name Here",
date: "2016-01-24",
charges: {
cosmetic: 25000.00,
medical: 25000.00,
total: 50000.00
},
payments: 75000,
appointments: 99,
pk: 5
},
]
];
更新:
我做了一些测试,得到了一些奇怪的结果。我在chrome的控制台里面执行了相同的代码,我的一切都运行得很好。但是,reducer仍然返回一个空数组。
更新#2 :
经过一些进一步的故障排除后,我想我可能会更好地了解导致状态写错的原因。我能够让传播操作员工作,因此数据不变性在这一点上并不是一个问题。
但是,在进行故障排除时我偶然注意到两件事。当redux状态改变时,不会更新保持我的redux状态的组件props。为了确认这一点,我使用subscribe方法在调度操作时给我状态。 rawdata
的字段填充了我在redux状态下查找的数据,但是,数据没有被推送到等效组件prop。
我注意到的第二件事是REMOVE_PROVIDER
操作没有调度,因为subscribe方法不会在控制台中报告任何内容。我不确定为什么会发生这种情况,但我认为filter
可能是原因,因为每当我尝试调度动作时,redux状态都不会受到影响。
在这一点上,我确信我遇到的问题更多的是反应 - 减少问题,而不是减速器本身的问题。我也冒昧地更新我的代码片段以反映我所看到的内容。
来自redux商店的答案 0 :(得分:0)
如果您的示例准确无误,则只需将REMOVE_PROVIDER案例更改为
即可case 'REMOVE_PROVIDER':
return newstate.filter((provider)=> provider[0].full_name.indexOf(action.data) === -1);
正如您在问题中所写的那样,过滤器将返回名称为"示例姓名在此处"的所有提供商。他们都不是。您希望相反,即返回名称与输入名称不匹配的所有提供商。
答案 1 :(得分:0)
首先,您的ADD_PROVIDER
正在直接改变state
,添加newstate = state
并不会复制状态数组,因为它只会创建对状态的引用。
对于ADD_PROVIDER
,action.data
是什么?根据你的动作,它本身已经是一个数组,但你用另一个数组符号包装它,你的状态变成了数组数组。 -____-?
正如另一个答案所示,您的REMOVE_PROVIDER
逻辑错误,您保留其全名prodiver
的所有action.data
。
要修复,你的减速器应该是:
export function Weeklystate(state=[], action){
switch(action.type){
case 'ADD_PROVIDER':
return [...state, action.data]; // this returns a new array
case 'REMOVE_PROVIDER':
// this will keep provider whose full_name does not have action.data
return state.filter((provider)=>provider[0].full_name.indexOf(action.data.full_name) === -1);
default:
return state;
}
}
正如我的第二点所暗示的,我不确定你希望你的州看起来像什么,所以要相应地修复。使用此代码,我假设ADD_PROVIDER
action.data是一个包含1个元素的数组。