環境
React:v18.3.1
Tips
- 複数階層で値を参照する時に便利なフック。(Propsのバケツリレーしなくてすむ)
(祖父コンポーネントで定義されたコンテキストの値を親コンポーネントと子コンポーネントから参照等)
複数階層で値を参照する
App.tsxの内容
import React, {
createContext, ReactNode, useEffect, useLayoutEffect,
} from 'react';
import Parent from './Parent.tsx';
export const TestContext: React.Context<any> = createContext(undefined);
const contextValue = {
id: 'ID1',
name: 'aiueo',
};
function App(): ReactNode {
useLayoutEffect(() => {
console.log('App useLayoutEffect');
});
useEffect(() => {
console.log('App useEffect');
});
return (
<TestContext.Provider value={contextValue}>
あいうえお
<Parent />
</TestContext.Provider>
);
}
export default App;
Parent.tsxの内容
import {
ReactNode, useContext, useEffect, useLayoutEffect, useState,
} from 'react';
import Child1 from './Child1.tsx';
import { TestContext } from './App.tsx';
function Parent(): ReactNode {
const [child1Value, setChild1Value] = useState<string>('Child1の初期値');
const [parentValue1, setParentValue1] = useState<string>('Parentの初期値');
const { id, name } = useContext(TestContext);
function parentBtnClickFunc() {
alert('parentBtnClickFunc');
setChild1Value('親からStateが変更されました');
}
useLayoutEffect(() => {
console.log('Parent useLayoutEffect');
console.log(`Parent ${id} ${name}`);
});
useEffect(() => {
console.log('Parent useEffect');
});
return (
<>
<div>
親:
{parentValue1}
</div>
<button type="button" onClick={parentBtnClickFunc}>
親ボタン
</button>
<Child1
childProp={child1Value}
parentStateFunc={setParentValue1}
/>
</>
);
}
export default Parent;
Child1.tsxの内容
import {
ReactNode, useContext, useEffect, useLayoutEffect,
} from 'react';
import { TestContext } from './App.tsx';
type Child1Props = {
childProp: string,
parentStateFunc: Function
};
function Child1({ childProp, parentStateFunc }: Child1Props): ReactNode {
const { id, name } = useContext(TestContext);
function childBtnClickFunc(): void {
alert('childBtnClickFunc');
parentStateFunc('子からStateが変更されました');
}
useLayoutEffect(() => {
console.log('Child1 useLayoutEffect');
console.log(`Child1 ${id} ${name}`);
});
useEffect(() => {
console.log('Child1 useEffect start Promise date = ', Date());
});
return (
<>
<div>
子:
{childProp}
</div>
<div>
<button
type="button"
onClick={childBtnClickFunc}
>
子ボタン
</button>
</div>
</>
);
}
export default Child1;
結果(コンソールの表示内容)
Child1 useLayoutEffect
Child1 ID1 aiueo
Parent useLayoutEffect
Parent ID1 aiueo
App useLayoutEffect
Child1 useEffect start Promise date = Thu May 16 2024 12:12:20 GMT+0900 (日本標準時)
Parent useEffect
App useEffect