
ReactにおけるABC問題
ReactにおけるABC問題とは
- CのonClickイベントハンドラ内の処理を起点にしてBを再描画させる
- Cは再描画させない
- Reactが標準で提供しているAPIのみを使用する
- コンポーネントのメモ化をしてはいけない
const A = () => { return ( <div> <p>This is A component.</p> <B /> <C /> </div> )}
interface BProps {}
const B = () => { // Bは再描画させたい
return ( <div> <p>This is B component.</p> </div> )}
interface CProps {}
const C = () => { // Cは再描画させない
return ( <div> <p>This is C component.</p> <button onClick={() => { // ここの処理の中でBを再描画させたい }} > Click </button> </div> )}
答え
useRef
を使った一番シンプルな答えがこれ。
import { MutableRefObject, useRef, useState } from 'react'
const A = () => { const setToggleRef = useRef<() => void>(() => {})
return ( <div> <p>This is A component.</p> <B setToggleRef={setToggleRef} /> <C setIsToggleRef={setToggleRef} /> </div> )}
interface BProps { setToggleRef: MutableRefObject<() => void>}
const B = ({ setToggleRef }: BProps) => { const [toggle, setToggle] = useState(false)
setToggleRef.current = () => { setToggle((current) => !current) }
return ( <div> <p>This is B component.</p> <p>Toggle: {toggle ? 'true' : 'false'}</p> </div> )}
interface CProps { setIsToggleRef: MutableRefObject<() => void>}
const C = ({ setIsToggleRef }: CProps) => { return ( <div> <p>This is C component.</p> <button onClick={() => { setIsToggleRef.current() }} > Click </button> </div> )}
参考
ちゃんとReactのドキュメント読もうね



