首页 > 解决方案 > 如何避免在反应功能组件中对“静态组件”进行不必要的重新渲染?

问题描述

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

const onTagSelectChange = (window: Window, 
    router: NextRouter, 
    name: string, 
    checked: boolean,
    tagSetter: React.Dispatch<React.SetStateAction<string>>) => {

    if (checked) {
        setTagQueryInUrl(window, router, name)
        tagSetter(name)
    } else {
        setTagQueryInUrl(window, router, null)
        tagSetter(null)
    }
}

const NewsList: NextPage = () => {

    const router = useRouter()
    const query = router.query as Query

    // store tag in state
    // initialize tag from `tag` query
    const [tag, setTag] = useState(query.tag)

    const { data: postsData, loading: postsLoading, error: postsError } = useQuery(
        POSTS_QUERY,
        {
            variables: {
                tag: tag
            }
        }
    )

    const { data: tagsData, loading: tagsLoading, error: tagsError } = useQuery(TAGS_QUERY)

    // show error page if either posts or tags query returned error
    if (postsError || tagsError) {
        return <Error statusCode={500} />
    }

    return (
        <div>
            <h1>Here we have list of news, and I should not re-render everytim :(</h1>
            <Tags
                loading={tagsLoading} 
                data={tagsData} 
                isChecked={(name) => name === tag} 
                onChange={(name, checked) => onTagSelectChange(window, router, name, checked, setTag)}
            />
            <Posts loading={postsLoading} data={postsData} />
        </div>
    )
}

我的问题是,为什么我的h1块会不断重新渲染,即使我没有传递任何东西给它?还是我完全误解了 react 的工作原理?

在这里我点击标签,它显示 h1 元素不断重新渲染

标签: javascriptreactjstypescriptreact-hooksnext.js

解决方案


React 组件在其状态或道具发生变化时重新渲染。如果我阅读正确,那么每当 url 更改时,您都会更改状态中的标签,从而使组件重新呈现自身。


推荐阅读