47ng / 47ng/nuqs

State desynchronization when rendering <Navigate /> on first render

Aberta
#1,245 3 comentários 1 reação 0 responsáveis Ver no GitHub
adapters/react-router bug
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

Abrir o 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

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.