目的
孫のイベントで親のステートを変更したい。
環境
- Node.js v14.15.0
- NPM v6.14.8
- React v17.0.1
- create-react-app v4.0.1
実装例
実装パターンを二通り試した。
コンポジションとは
https://reactjs.org/docs/composition-vs-inheritance.html
コンポジションと継承について、いくつかの例とともに書かれている。
https://reactjs.org/docs/context.html#before-you-use-context
contextを使う前にコンポジションを考慮しようと書かれている。
実装例
Parent.js
import { useState } from "react"; import { Child } from "./Child"; import { GrandChild } from "./GrandChild"; export const Parent = () => { const [count, setCount] = useState(0); const countUp = () => { setCount(count + 1); }; const grandChild = (<GrandChild countUp={countUp}></GrandChild>) return ( <div> <p>Parent component</p> <p>{count}</p> <Child grandChild={grandChild}></Child> </div> ); };
Child.js
export const Child = (props) => { return ( <div> <p>Child component</p> {props.grandChild} </div> ); };
GrandChild.js
export const GrandChild = (props) => { return ( <div> <p>GrandChild Component</p> <button onClick={props.countUp}> GrandChild Button </button> </div> ); };
コンテクストとは
https://reactjs.org/docs/context.html
コンテクストの概念について書かれている。
https://reactjs.org/docs/hooks-reference.html#usecontext
hooksで実装するパターンについて書かれている。
実装例
Parent.js
import { useState } from "react"; import { Child } from "./Child"; import { ClickEventContext } from "./hogeContext"; export const Parent = () => { const [count, setCount] = useState(0); const countUp = () => { setCount(count + 1); }; return ( <div> <p>Parent component</p> <p>{count}</p> <ClickEventContext.Provider value={{ onClickEvent: countUp }}> <Child></Child> </ClickEventContext.Provider> </div> ); };
Child.js
import { GrandChild } from "./GrandChild"; export const Child = () => { return ( <div> <p>Child component</p> <GrandChild></GrandChild> </div> ); };
GrandChild.js
import { useContext } from "react"; import { ClickEventContext } from "./hogeContext"; export const GrandChild = () => { const clickEventContext = useContext(ClickEventContext) return ( <div> <p>GrandChild Component</p> <button onClick={clickEventContext.onClickEvent}>GrandChild Button</button> </div> ); };
GrandChildのクリックイベント用コンテキスト
ClickEventContext.js
import { createContext } from "react"; export const ClickEventContext = createContext({ onClickEvent: () => {} });
まとめ
今回の用途ならContextAPIをせずコンポジションのほうが良いと判断した。
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.