gpt4 book ai didi

javascript - 在 React 功能组件中多次调用函数

转载 作者:行者123 更新时间:2023-12-05 09:10:30 26 4
gpt4 key购买 nike

下面是组件文件SinglePostBySearch.js

import React, { useState } from 'react'
import Post from './Post'
const axios = require('axios')

const getElt=({loading},{isThereQuery},{posts})=>{
console.log(posts)
if(!loading && isThereQuery)
{
return(
<Post post={posts} id={posts.id} />
)
}
if(loading)
{
return <div>Loading</div>
}
if(!(loading && posts))
{
return <div>No post from the user</div>
}
}

function SinglePostBySearch(props) {
const [posts, setPosts] = useState({})
const [isThereQuery,setIsThereQuery]=useState(false)
const [loading,setIsLoading]=useState(false)
const fetchPost = (event) => {
const postId = event.target.value
if (postId) {
setIsThereQuery(false)
setIsLoading(true)
axios.get(`https://jsonplaceholder.typicode.com/posts/${postId}`).then(res => {
setPosts(res.data)
setIsThereQuery(true)
setIsLoading(false)
}).catch(err => {
console.log(err)
setIsLoading(false)
setPosts({})
})
}
else{
setPosts({})
setIsThereQuery(false)
}

}
return (
<div>
Hello {props.username}, enter a <strong>userId</strong> below
<input type="text" onChange={fetchPost} />
{getElt({loading},{isThereQuery},{posts})}
</div>
)
}
export default SinglePostBySearch

问题/疑问:在功能组件的返回中,在第三行,我正在调用另一个函数 getElt。它似乎被调用了大约 4 或 5 次,这是我从插入到 getElt 函数第一行的 console.log 中得出的。我想知道为什么它应该只被调用一次,却被调用了这么多次。

我想指出的是,函数 getElt

返回的子组件 Post 中没有任何控制台日志语句

最佳答案

这是当今 React 中的一种误解。许多人认为如果 props 和 state 不改变,函数组件就不会被调用。事实上,当父组件重新渲染时,您的函数可能会被调用多次,React 会检查旧的 Shadow DOM 以查看它是否与新的 Shadow DOM 匹配。我们可以说的是,如果 props 和 state 没有改变,返回的 JSX 将不会在真实的 DOM 中更新。

要减少 React 引擎调用您的函数组件的次数,您可以做的是尽量避免您的组件进行不必要的更新(包括您的父组件)。以下是我在查看您的代码时看到的几件事:

  1. 每次调用您的函数时都会创建一个新的 fetchPost 实例。这意味着在每次执行时,它都会有不同的内存地址。然后它作为 props 传递给子组件,这意味着每次执行 SinglePostBySearch 组件时,子组件都将被强制渲染。您可能在父组件中遇到类似情况,导致该组件被过度调用。为避免这种情况,您作为 prop 传递给 children 的任何函数都应包装在 useCallback 中,以便正确内存,并且不会每次都重新创建一个新实例。

  2. 每次执行组件函数时,您都在调用 getElt 函数,即使数据没有更改也是如此。如果您需要防止函数执行这么多次,useMemouseCallback(取决于用例)并指定依赖项(loading, isThereQuery, posts) 在 Hook 的 deps 数组中。这样,只有在修改任何这些依赖项时才会重新计算该函数。

  3. 您将 loadingisThereQueryposts 包装在一个匿名对象 {} 中你传递它们的时间。每次看到它时都会实例化一个新对象,这意味着它有一个新的内存地址——并且会导致您将它作为 Prop 传递给的任何子对象重新渲染。 useState Hook 已经维护了值的内存地址,因此通过将其包装在新对象中,您可能会导致问题。

在 React 中,每当您使用插值直接在 JSX 中绑定(bind)数据时({getElt({loading},{isThereQuery},{posts})}),React 都认为这是一个子元素。我不确定匿名对象将如何影响这一点,但摆脱包装每个参数的多余对象并没有坏处,尤其是因为你在 getElt 函数中再次解构它们.

关于javascript - 在 React 功能组件中多次调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61394328/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com