Reactjs 仅当状态与当前值不同时,如何在react钩子中设置状态
我有以下代码Reactjs 仅当状态与当前值不同时,如何在react钩子中设置状态,reactjs,request,react-hooks,Reactjs,Request,React Hooks,我有以下代码 setInterval(() => { fetch(`/clusters?type=${type}`) .then((response) => response.json() .then((responseBody) => { if(clusters !== responseBody.members)
setInterval(() => {
fetch(`/clusters?type=${type}`)
.then((response) => response.json()
.then((responseBody) => {
if(clusters !== responseBody.members)
setClusters(responseBody.members);
}))
.catch();
}, 5000);
由于在检查
时,会异步设置集群,如果(集群!==responseBody.members)
集群始终为空,那么哪种方法正确?我尝试这样做是为了减少渲染次数,因为该请求每5秒发生一次,这是因为您得到的状态已经过时了。您可以使用useRef
创建一个ref,然后在另一个useffect
中使用当前状态值更新ref。获取数据后,使用ref将其与状态进行比较,如下所示:
函数应用程序(){
const[clusters,setClusters]=useState([]);
const clustersRef=useRef(集群);
useffect(()=>{
clustersRef.current=集群;
});
useffect(()=>{
设置间隔(()=>{
获取(`/clusters?type=${type}`)
.then((response)=>response.json()
.然后((响应体)=>{
if(clustersRef.current!==responseBody.members)
setClusters(responseBody.members);
}))
.catch();
}, 5000);
}, []);
}
希望这有帮助:)您可以将一个函数传递给setClusters
,以获取当前状态作为参数。然后,您可以比较并返回新项(如果有新项),或者返回旧值(如果没有任何更改)。React非常聪明,知道如果将state设置为完全相同的值,它不应该重新渲染
但你还有一个问题。如果您的状态没有更改,React已经足够智能,不会重新渲染。但是你的状态正在改变。您的api调用正在创建新的数据对象,这些数据对象将无法直接与旧数据对象进行比较
因此,您需要找到一种更好的方法来检测是否发生了变化。==
或==
不会告诉您有两个数组具有相同的项,它们会告诉您它们是否是相同的数组实例
[1,2,3] === [1,2,3] //-> false
因此,您必须想出一种方法来判断是否有两个数组包含相同的内容。一种方法是从旧数据和新数据创建一个ID字符串,然后比较它们。(假设clusters
是一个对象数组,其中包含一些uniqid
)。您可以创建一个可以与另一个值进行比较的值,以查看是否有任何更改
setClusters(prevClusters => {
const prevIds = prevClusters.map(member => member.id).sort().join('-')
const newIds = responseBody.members.map(member => member.id).sort().join('-')
if (newIds === prevIds) {
return prevClusters // nothing has changed, return previous value
} else {
return responseBody.members // return new values.
}
})
如果数据未更改,则不应导致重新渲染。ReactJS足够聪明,只在出现差异时才进行渲染。正如@AlexWayne所说的[1,2,3]!==[1,2,3]/->真的
是的,我的错,你不能像那样比较数组,所以要比较它们,你需要把它们的ID串起来,然后比较它们,或者比较那些数组的长度。然后,你可以想出一个简单的算法,告诉你是否有相同的数据。我不可能知道你的数据模型。