React のコンテキストの仕組みは useContext を使ったコンポーネントからもっと近い親のプロバイダーコンポーネントの value に渡された値を取得するというもの
ネストしたときに一番近いものを参照できていいんだけど あるイベントが起きた回数を共有するみたいなときに最も近いコンテキストだけじゃなくて更に上にも伝わってほしい
標準の仕組みでそういうことをするものはなさそうなので 自分でそうなるように作る

基本の形

const CounterContext = createContext()
const CounterProvider = CounterContext.Provider
const useCounter = () => useContext(CounterContext)

const useNewCounter = () => {
const [count, setCount] = useState(0)
return {
count,
up: () => setCount(x => x + 1)
}
}

const Parent = () => {
const counter = useNewCounter()
return (
<CounterProvider value={counter}>
<Button />
<hr />
<Child />
<hr />
<Button />
</CounterProvider>
)
}

const Child = () => {
const counter = useNewCounter()
return (
<CounterProvider value={counter}>
<Button />
<Button />
</CounterProvider>
)
}

const Button = () => {
const counter = useCounter()
return (
<button onClick={counter.up}>{counter.count}</button>
)
}

単純にネストしただけなので これだと Child の中のボタンを押しても Child のカウンターしか増えない
Child をこうして Parent のカウンターの up も呼び出す

const Child = () => {
const counter = useNewCounter()
const parent_counter = useCounter()
const chain_counter = {
...counter,
up: () => {
counter.up()
parent_counter.up()
},
}
return (
<CounterProvider value={chain_counter}>
<Button />
<Button />
</CounterProvider>
)
}

毎回書きたくないのでフックにまとめる

const useChainCounter = () => {
const parent_counter = useCounter()
const counter = useNewCounter()
return {
...counter,
up: () => {
counter.up()
parent_counter?.up()
}
}
}

const Child = () => {
const chain_counter = useChainCounter()
return (
<CounterProvider value={chain_counter}>
<Button />
<Button />
</CounterProvider>
)
}