Javascript 如何避免不必要的“重新渲染”;“静态组件”;在功能部件中?

Javascript 如何避免不必要的“重新渲染”;“静态组件”;在功能部件中?,javascript,reactjs,typescript,react-hooks,next.js,Javascript,Reactjs,Typescript,React Hooks,Next.js,我有一个react功能组件,它显示标签和帖子列表+一些静态文本/装饰。我使用useStatehook将当前选择的标记存储在一个状态中。使用apollo的useQueryhook和tag变量获取帖子。用户应该能够选择一个标记,它将替换当前的标记状态-因此useQuery(POSTS\u QUERY)将使用新的标记变量重新运行 const onTagSelectChange=(窗口:窗口, 路由器:NextRouter, 名称:string, 选中:布尔, 标记设置器:React.Dispatch)

我有一个react功能组件,它显示标签和帖子列表+一些静态文本/装饰。我使用
useState
hook将当前选择的标记存储在一个状态中。使用apollo的
useQuery
hook和
tag
变量获取帖子。用户应该能够选择一个标记,它将替换当前的
标记
状态-因此
useQuery(POSTS\u QUERY)
将使用新的
标记
变量重新运行

const onTagSelectChange=(窗口:窗口,
路由器:NextRouter,
名称:string,
选中:布尔,
标记设置器:React.Dispatch)=>{
如果(选中){
setTagQueryInUrl(窗口、路由器、名称)
标记设置器(名称)
}否则{
setTagQueryInUrl(窗口、路由器、空)
标记设置器(空)
}
}
常量新闻列表:下一页=()=>{
const router=useRouter()
const query=router.query作为查询
//以状态存储标签
//从“tag”查询初始化标记
const[tag,setTag]=useState(query.tag)
const{data:postsData,loading:postsLoading,error:postsError}=useQuery(
发帖询问,,
{
变量:{
标签:标签
}
}
)
const{data:tagsData,load:tagsLoading,error:tagsError}=useQuery(TAGS\u QUERY)
//如果POST或tags查询返回错误,则显示错误页
if(postsError | | tagsError){
返回
}
返回(
这里是新闻列表,我不想每次都重新呈现:(
名称===标记}
onChange={(名称,选中)=>onTagSelectChange(窗口,路由器,名称,选中,设置标签)}
/>
)
}
我的问题是,为什么我的
h1
块在没有传递任何信息的情况下仍继续重新渲染?还是我完全误解了react的工作原理


只要状态或道具发生变化,React组件就会重新呈现。如果我读得正确,那么只要url发生变化,您就会在状态中更改标记,从而使组件重新呈现自身。

当您的状态在
新闻列表中声明时,任何状态都会发生变化(如另一个用户在回答中所述)将触发对整个组件(NewList)的重新呈现,而不仅仅是对已传递状态的组件(从而对其中的静态
进行重新呈现)

如果此组件的某些部分与此状态无关,则可以将它们移到外部以避免重新渲染

但是,在这种情况下,重新呈现您的
并不是React的成本。您应该担心,在发生更复杂事情(例如填充列表或计算内容等)的自定义组件上遵循这种方法在这些情况下,如果不受父的状态改变的影响,您不希望所有这些复杂的事情再次发生。您也应该“强”总是< /强>考虑,如果移动外部组件是有意义的,或者这样做,则会使代码复杂化。


您应该始终在组织良好的代码和高效的代码之间取得平衡。

您应该检查元素面板,查看
元素是否实际发生了更改。您看到的重新渲染可能是因为
元素的兄弟元素正在被修改,因此它们的共享父元素得到了回流。您还可以通过将
移动到
之外,使其不再是兄弟姐妹来测试这一点。这是否回答了您的问题?@emilebergron不,我没有将任何道具传递给
元素,因此这不适用于我的情况。但是封闭组件重新呈现,其中也包括其所有子元素。@Wex我看了一眼是的,你是对的,
没有被修改。看起来
是被修改的,有一个
被添加了很快的毫秒,但我不记得添加了任何
是的,我正在更改
onTagSelectChange
中的
标记状态。但是不是其他的不接收任何道具的er组件不应重新渲染?