状態
- Next.js: 15.3.0 (App Router)
- React.js: ^19.0.0
- urql: ^4.2.2
事象
codegen を使用し作成した useQuery のラッパー(データをリストで取得)を A, B page (component) で使用していた。B は A の子 compornent です。A -> B に遷移するときは何も起こらないが、B -> A にブラウザバックした時 "Cannot update a component X while rendering a different component Y. To locate the bad setState() call inside aPage
, follow the stack trace as described in ...." が発生。
Apage
import { useGetSomethingQuery, gql } from 'urql'
const APage = () => {
const [{data, fetching, error}] = useGetSomethingQuery()
const [aData, setAData] = useState(null)
useEffect(() => {
setData(data)
},[data])
return ...
}
gql`
query GetSomething {
id
name
...
}
`
BPage
import { useGetSomethingQuery, gql } from 'urql'
const BPage = () => {
const [{data, fetching, error}] = useGetSomethingQuery()
const [bData, setBData] = useState(null)
useEffect(() => {
setBData(data)
},[data])
return ...
}
解決策
同じGQLであっても再利用せず、ユニークな命名にすることで解決した
Apage
import { useGetSomethingQuery, gql } from 'urql'
const APage = () => {
const [{data, fetching, error}] = useGetSomethingQuery()
const [aData, setAData] = useState(null)
useEffect(() => {
setData(data)
},[data])
return ...
}
gql`
query GetSomething {
id
name
...
}
`
BPage
import { useGetSomethingForBQuery, gql } from 'urql'
const BPage = () => {
const [{data, fetching, error}] = useGetSomethingForBQuery()
const [bData, setBData] = useState(null)
useEffect(() => {
setBData(data)
},[data])
return ...
}
gql`
query GetSomethingForB {
id
name
...
}
`
エラー調査
- useStateが予期せぬタイミングで呼ばれてエラーが発生している可能性
useEffectを使用し副作用の中でsetStateしていたので問題なし
AIに聞いたりAgentを使用してもこの修正を行えば直ると提示されたが修正できなかった - codegenされたものに何かしらのエラーがある可能性
schemaやgqlを確認したが想定通り宣言できていた - StrictModeが悪さしている?
関係なし - ReactのConcurrent featuresが影響している?
調べたがよくわからなかった