Skip to content

Prevent duplicate render of the initial page in React #2377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 17, 2025

Conversation

pascalbaljet
Copy link
Member

This took some serious debugging, but I found the reason why the React package renders the initial page twice!

If you follow in the core package: router.init() => InitialVisit.handle() => InitialVisit.handleDefault(), then handleDefault will call set() on the currentPage page instance. At the end of that method, it will call this.swap which essentially calls the swapComponent callback from the packages.

So, in the React package we have:

const [current, setCurrent] = useState({
  component: initialComponent || null,
  page: initialPage,
  key: null,
})

useEffect(() => {
  router.init({
    // ...
    swapComponent: async ({ component, page, preserveState }) => {
      setCurrent((current) => ({
        component,
        page,
        key: preserveState ? current.key : Date.now(),
      }))
    },
  })

  // ...
}, [])

This would call setCurrent but with the same object as that was initially set in useState(), which then leads to a rerender. I've introduced a currentIsInitialPage variable to prevent this from happening, just once on the initial page.

@pascalbaljet pascalbaljet added the react Related to the react adapter label Jun 13, 2025
@pascalbaljet
Copy link
Member Author

Broken after merging #2379, investigating now.

@chack1172
Copy link
Contributor

@pascalbaljet what is broken? I tried your change with both using my variable or an entra variable and it works fine

@pascalbaljet
Copy link
Member Author

@chack1172 I'm not sure yet, but the CI fails: https://github.com/inertiajs/inertia/actions/runs/15702617146/job/44240823829

Both variants work locally, so I hope it's just a CI issue and not some timing issue due to the CI being slow.

@chack1172
Copy link
Contributor

@pascalbaljet I found the issue. In playwright tests, the dump function in router.init() is called at first render, instead of the swap component set later on useEffect. In browser it works correctly and call the correct swapComponent.
To fix it just set currentIsInitialPage = false in the dump function

@pascalbaljet
Copy link
Member Author

@chack1172 Thanks, got it!

@pascalbaljet pascalbaljet merged commit a40806a into master Jun 17, 2025
8 checks passed
@pascalbaljet pascalbaljet deleted the prevent-double-inital-load-react branch June 17, 2025 10:54
@chack1172
Copy link
Contributor

@pascalbaljet you reverted the variable back inside the App component, this can cause issues

@pascalbaljet
Copy link
Member Author

@pascalbaljet you reverted the variable back inside the App component, this can cause issues

Whoops! Thanks for pointing out, I've opened #2381 for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
react Related to the react adapter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants