Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid unnecessary re-render for "static components" in react functional component?

I have a react functional component that shows list of tags and posts + few static text/decorations. I store the currently selected tag in a state using useState hook. Posts are fetched by using apollo's useQuery hook with tag variable. User should able to select a tag and it will replace the current tag state - thus the useQuery(POSTS_QUERY) will re-run with new tag variable.

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>
    )
}

My question is, why is my h1 block keeps re-rendering even though I don't pass anything to it? Or do I completely misunderstand how react works?

Here I click on tags, and it shows h1 element keeps re-rendering

like image 839
fullmoon6661 Avatar asked Jul 04 '26 09:07

fullmoon6661


2 Answers

React components re-render whenever their state or props change. If I am reading this correctly then you are changing tag in state whenever the url changes and thus making the component to re-render itself.

like image 78
Vaintti Avatar answered Jul 07 '26 00:07

Vaintti


As your state is declared on your NewsList component, any state change (as another user stated on his answer) will trigger a re-render of the whole component (NewList) and not only to the components that you have passed your state (thus to the static <h1> you have in there).

If there are parts of this component that have nothing to do with this state, you can move them outside to avoid the re-render.

Though, on cases like this, re-rendering your <h1> is not a cost for React. You should worry and follow this approach on custom components where more complex things going on (e.g. populating lists or calculating stuff etc..). In those cases, you don't want all this complex stuff to happen again, if they are not affected by a parent's state change. You should also always consider, if moving the component outside makes sense or by doing so, you make your code complex.

You should always strike a balance between well-organized and efficient code.

like image 44
Michalis Garganourakis Avatar answered Jul 07 '26 01:07

Michalis Garganourakis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!