State desynchronization when rendering <Navigate /> on first render
- Linguagem predominante
- TypeScript
- Estrelas
- 10.8k
- Forks
- 294
- Merge médio
- 1d 16h
- PRs com merge (30d)
- 21
Descrição
## Context
What's your version of `nuqs`?
```
"nuqs": "2.8.2",
```
What framework are you using?
- ❌ Next.js (app router)
- ❌ Next.js (pages router)
- ✅ React SPA (no router)
- ❌ Remix
- ✅ React Router
Which version of your framework are you using?
```
"react-router": "^6.30.2",
"react-router-dom": "^6.30.2",
```
## Description
When rendering a `` component which updates the search params on first render, `nuqs` state will never synchronize its state back.
## Reproduction
```typescript
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { parseAsString, useQueryStates } from 'nuqs';
import { NuqsAdapter } from 'nuqs/adapters/react-router/v6';
import { BrowserRouter, Link, Navigate } from 'react-router-dom';
import { describe, expect, test } from 'vitest';
function TestComponent() {
const [nuqsState] = useQueryStates({
search: parseAsString.withDefault(''),
});
if (nuqsState.search === 'REDIRECT') {
return (
);
}
return (
<>
{nuqsState.search}
Trigger redirect
);
}
describe('nuqs repro', () => {
test('with initial search param', async () => {
using _ = withInitialUrl('/?search=foo');
const { container } = render(
,
);
expect(container).toHaveTextContent('foo');
});
test('with a click on a link which triggers the rendering of ', async () => {
using _ = withInitialUrl('/?search=foo');
const user = userEvent.setup();
const { container, getByRole } = render(
,
);
const redirectButton = getByRole('link', { name: 'Trigger redirect' });
await user.click(redirectButton);
expect(container).toHaveTextContent('foo');
});
test('with initial search param', async () => {
/**
* With this URL, will render on first render.
*/
using _ = withInitialUrl('/?search=REDIRECT');
const { container } = render(
,
);
await expect.poll(() => container).toHaveTextContent('foo');
});
});
function withInitialUrl(url: string) {
window.history.pushState({}, '', url);
return {
[Symbol.dispose]: () => {
window.history.pushState({}, '', '/');
},
};
}
```
Guia de contribuição
Direção de pesquisa
O problema está no adaptador nuqs para React Router v6, provavelmente na lógica de sincronização entre os parâmetros de pesquisa da URL e o estado interno quando um componente Navigate é acionado na primeira renderização. Comece examinando o módulo adapters/react-router/v6, particularmente como ele escuta as alterações da URL e atualiza o estado. O teste de reprodução mostra o cenário exato da falha; execute a suíte de testes fornecida para ver a dessincronização. Procure onde o estado é definido na renderização inicial e como ele reage a uma alteração da URL causada por Navigate.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Domínio
- frontend
- Tipo de issue
- Bug
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Status de atividade
- Estagnada
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 45/100