我试图排序数组,并反映其排序结果立即使用状态钩子。我已经新的反应是检测其状态变化的Object.is()
,所以试图传播数组之前使用useState
如下所示;
const [reviews, setReviews] = useState([...book.reviews]);
useEffect(() => {
const sortedReviews = [...reviews]
.sort((review1: IReview, review2: IReview) =>
sortBy(review1, review2, sortRule));
setReviews([...sortedReviews])
}, [sortRule])
排序后,我检查了变量sorted评论
的值,它按预期进行了排序,但反应并没有重新渲染页面,所以这种排序没有反映到用户界面。
我已经搜索了解决方案,似乎很多人可以通过在调用useState
之前传播一个数组来解决这个问题,就像这个堆栈溢出解释的那样:为什么useState没有触发重新渲染?。任何帮助将非常感谢。谢谢你!
[新增]我的渲染部分如下:;
<>
{
sortedReviews
.map((review: IReview) => (
<ReviewBlock id={review.id}
review={review}
targetBook={book}
setTargetBook={setBook}/>
))
}
</>
当组件不重新渲染时,几乎总是由于状态的变化。这里您正在调用审阅
上的变异操作.sort
。在变异之前,您需要传播数组。
useEffect(() => {
const sortedReviews = [...reviews].sort((review1: IReview, review2: IReview) =>
sortBy(review1, review2, sortRule)
);
setReviews(sortedReviews);
}, [sortRule]);
但这里还有其他问题reviews
不是useEffect的依赖项,因此我们希望使用setReviews
回调,如setReviews(当前=
通常,排序数据作为
usemo
比作为useState
更有意义。sortRule
是一种状态,sortedReviews
就是从中派生出来的。
调用
sortBy
作为比较函数的方式感觉有点不对劲。也许只是个让人困惑的名字?
此外,如果
书籍
正确键入为{reviews:IReview[]}
,则不需要在回调中包含类型IReview
。
如果您包括
sortBy
函数和sortRule
变量,那么我可以提供更多帮助。但这是我想到的。
import React, { useState, useMemo } from "react";
type IReview = {
rating: number;
}
type Book = {
reviews: IReview[]
}
type SortRule = string; // just a placeholder - what is this really?
declare function sortBy(a: IReview, b: IReview, rule: SortRule): number;
const MyComponent = ({book}: {book: Book}) => {
const [sortRule, setSortRule] = useState("");
const reviews = book.reviews;
const sortedReviews = useMemo( () => {
return [...reviews].sort((review1, review2) =>
sortBy(review1, review2, sortRule)
);
}, [sortRule, reviews]);
...
}
打字游戏链接
有时我也会遇到这个问题,在我的例子中,我只是“强制”渲染调用回调。
第一个解决方案:
const [reviews, setReviews] = useState([...book.reviews]);
useEffect(() => {
const sortedReviews = [...reviews]
.sort((review1: IReview, review2: IReview) =>
sortBy(review1, review2, sortRule));
setReviews(()=> [...sortedReviews]) // <-- Here
}, [sortRule])
第二个解决方案:可以使用useRef实时获取数据,见下文:
const [reviews, setReviews] = useState([...book.reviews]);
const reviewsRef = useRef();
useEffect(() => {
const sortedReviews = [...reviews]
.sort((review1: IReview, review2: IReview) =>
sortBy(review1, review2, sortRule));
setReviewRef([...sortedReviews])
}, [sortRule])
function setReviewRef(data){
setReview(data);
reviewsRef.current = data;
}
所以,取而代之的是使用状态评论使用reviewsRef.current作为u数组
我希望你能解决这个问题!
为了在处理JavaScript对象时通过另一个对象继承一个对象的属性,我经常看到使用,其目的是创建一个具有另一个对象属性的对象,然后对其进行扩展。 为什么我们不能只使用与扩展对象更相关的 ? 请告诉我这两者之间的区别,以及为什么我们不能而不是这是一个昂贵的操作。
我想制作一份扩展的副本,作为我自己扩展的基础。我如何克隆一个TYPO3扩展,以同样的行为开始我自己的扩展。我必须更改哪些文件和参数?
我是新来的反应。作为一个学习练习,我正在构建一个国际象棋应用程序 我想根据父级中的状态更改子级的DOM。当前,在父级组件的状态变化时,子级组件没有变化。 PS:请忽略任何语法错误。这段代码是实际代码的精简。如果你想看完整的代码,请看这里
问题内容: 我有ng-table的页面,可以很好地处理初始数据。我有一个选择框,该框根据选择的选项发送服务器请求,然后Iam将新数据获取为angular,但未使用ng- table更新。 这是我的看法: 我的控制器: 问题答案: $scope.$watch(‘result’, function () { $scope.tableParams.settings().$scope = $scope;
问题内容: 假设我已经定义了这样的协议: 现在,我想扩展并采用该协议。 但是下面的代码: 由于错误而无效 错误:必须在非专用泛型类型“ Array”上声明受约束的扩展,并使用“ where”子句指定约束 我发现类似的问题,但建议的解决方案是使用,但在这种情况下它会导致错误: 错误:协议“ CollectionType”只能用作一般约束,因为它具有“自我”或相关类型要求 有什么解决办法吗? 编辑:
问题内容: 我知道您不能动态扩展普通数组,但这是一种有效的方法吗? 我知道比尝试使用普通数组更好的方法,但是我想首先使用普通数组来解决这个问题。 我的愿望是,它从0 + 1(so 1)开始,在被称为new时,它的大小与相同,然后保持不变,同时再次声明,然后将其复制回新的大小。这对我来说很有意义,但我总是会遇到异常情况? 问题答案: 该方法不会更改OrigArray的值;它所做的只是在其中存储一个克