英文:
Challenges with useEffect, useState
问题
我认为目前我的代码行为似乎是prepareList
没有及时更新,因此未定义,然后代码出错,显示filter不是一个函数,并且如果没有prepareList.length
,它会返回finalGroups
,我确信prepareList
内部的映射本身有效,removedSubstitutesList
后面有值(对象数组),它本身是useState
数组。
正如您所看到的,我已经尝试通过添加完全无关的useEffect
和makeWay
以及在其中执行setWait
来防止这种行为,只是为了等待更长时间以获取到prepareList
的值。此外,依赖项列表是尝试让它以某种方式工作以查看出错的一部分。
**我的问题是:**我的reduce函数本身是否有问题,因此它不起作用,或者它确实是useState
、多次渲染等的问题,因此在没有值的情况下reducer函数运行得太早,或者还有其他我没有注意到的问题。
此代码是更大代码集的一部分,此部分旨在收集、处理并将准备好的数据提升到主应用程序组件以供其使用。Sendpressed在这里是一个按钮点击事件,liftSubstitutes和liftSubstituteGroups是将数据发送到主应用程序组件的回调函数。
希望我已经足够清楚,以便您可以跟进,如果不清楚,我会尽力指导您。欢迎任何建议,提前感谢。
useEffect(() => {
const makeWay = () => {
setWait('a');
};
makeWay();
}, [sendPressed, finalGroups, removedSubstitutesList]);
useEffect(() => {
const liftFinalData = () => {
const prepareList = removedSubstitutesList.map(item => item.email);
const finalResults = !prepareList.length
? finalGroups
: prepareList.reduce(
(results, filter) => results.filter(filter),
finalGroups[0].data
);
liftSubstitutes(Substitutes || 0);
liftSubstituteGroups(finalResults || 0);
};
liftFinalData();
}, [sendPressed, finalGroups, wait]);
英文:
I think the way my code is behaving at the present moment it seems that prepareList
doesn't update in time and thus is undefined and then code gives an error saying filter is not a function, and it returns finalGroups
as it should if there is no prepareList.length
. I'm certain that the map inside prepareList
itself works and there are values (array of objects) behind removedSubstitutesList
which itself is useState
array.
As you can see I've tried to prevent this behavior by adding completely irrelevant useEffect
and makeWay
and by doing setWait
inside of it just to make it wait a bit longer to be able to get values to prepareList
. Also dependencylists are part of trying to get it working somehow to see what is wrong.
My question is: is my reduce function itself wrong and thus it doesn't work or if it is indeed the problem of useState
, multiple renderings etc. so that reducer function runs too early without a value or is there something else that I haven't noticed.
This code is a part of a bigger set and this part is supposed to gather, process and lift up prepared data to the main app component for it to use. Sendpressed here is a buttonclick and liftSubstitutes and liftSubstituteGroups are callbacks to send data to main app component.
Hopefully I've managed to be clear enough to follow through and if not I'll try my best to guide you through it. Any suggestions are welcomed, thanks in advance.
useEffect(() => {
const makeWay = () => {
setWait('a');
};
makeWay();
}, [sendPressed, finalGroups, removedSubstitutesList]);
useEffect(() => {
const liftFinalData = () => {
const prepareList = removedSubstitutesList.map(item => item.email);
const finalResults = !prepareList.length
? finalGroups
: prepareList.reduce(
(results, filter) => results.filter(filter),
finalGroups[0].data
);
liftSubstitutes(Substitutes || 0);
liftSubstituteGroups(finalResults || 0);
};
liftFinalData();
}, [sendPressed, finalGroups, wait]);
答案1
得分: 0
你的假设是正确的,问题出在reduce()
中的filter()
。
所以Array.prototype.reduce()
接受两个参数:
- 第一个是累加器,在你的情况下是
finalGroups[0].data
,看起来没问题。 - 第二个是迭代中的当前值 -
filter
变量。
所以在你的情况下,我猜问题在于如错误消息所述,filter
不是一个函数。从技术上讲,在这种情况下,filter
是来自 prepareList
数组的一个元素。
对于 Array.prototype.filter()
,你需要传递一个返回 true
或 false
值的函数,根据提供的函数来实现测试的元素将创建一个新数组。
考虑以下解决方案:
(results, prepareListElem) => results.filter(element => {
var passTest = false;
// 实现 passTest 的逻辑
return passTest;
})
提供一个可以工作的示例来说明reduce()
和filter()
的工作方式:
const array = [{name: 'John'}, {name: 'Jane'}];
const result = array.reduce((acc, cur) => {
acc.push({
...cur,
age: 12
});
return acc;
}, []);
console.log(result);
const filtered = result.filter(e => e.name.indexOf('a') !== -1);
console.log(filtered);
在我的示例中,我们有一个包含所有对象都具有 name
属性的数组。我们试图扩展它们的 age
属性。最后,我们通过筛选 name
属性包含字符 a
的对象来进行过滤。
希望这有助于解决你遇到的问题并澄清了问题所在!
英文:
Your assumption is correct, the issue is with filter()
in reduce()
.
So Array.prototype.reduce()
takes 2 arguments:
- The first is the accumulator, in your case
finalGroups[0].data
which looks okay. - The second is the current value from the iteration -
filter
variable.
So in your case I guess the issue is that as the error message states that filter
is not a function. Technically filter
in this case one element from prepareList
array.
For Array.prototype.filter()
you need to pass a function which return true
or false
value, from the documentation:
> The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Think about the following solution:
(results, prepareListElem) => results.filter(element => {
var passTest = false;
// the logic to implement for passTest
return passTest;
})
Giving one working example how reduce()
and filter()
are working:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const array = [{name: 'John'}, {name: 'Jane'}];
const result = array.reduce((acc, cur) => {
acc.push({
...cur,
age: 12
});
return acc;
}, []);
console.log(result);
const filtered = result.filter(e => e.name.indexOf('a') !== -1);
console.log(filtered);
<!-- end snippet -->
In my example, we have elements in an array where all the object has name
property. We are trying to extend with age
. At the end we are filtering where the name
property contains character a
.
I hope this helps and clarifies where you have issues!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论