LiSMO techの小谷です。今回はReact.jsのContext機能について紹介します。
React.jsの使用経験のある方はもうご存知かと思いますが、親コンポーネントから子コンポーネントへのpropsの受け渡しはコンポーネントが増えて複雑になっていくほどつらいですよね。
今回はこのpropsの受け渡し(props drilling)を解決する方法のひとつであるReactのContext機能を紹介します。
また、前回作成したファイルを引き継いで作業するので、前回の記事を確認したい方は以下を参考にして下さい。
初めに今回のこの記事でやりたいことを上げておきます。
// app.js
import Top from './pages/top';
import Setting from './pages/setting';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { useReducer } from 'react';
import SettingContext from './contexts/setting';
function App() {
const initialState = {
backgroundColor: 'white'
}
function reducer(state, color) {
return { backgroundColor: color };
}
const [state, dispatch] = useReducer(reducer, initialState);
return (
<SettingContext.Provider value={{state, dispatch}}>
<BrowserRouter>
<Routes>
<Route path="/" element={<Top />} />
<Route path="setting" element={<Setting />} />
</Routes>
</BrowserRouter>
</SettingContext.Provider>
);
}
export default App;
このファイルは上位のコンポーネントで、画面のルーティングをしています。
ここでContextの初期値やContextで使用する関数も定義しています。この定義をProviderに渡してあげて、Provider配下のトップ画面と設定画面でも使えるようにしています。
// pages/top.js
import { useState, useContext } from 'react';
import { Link } from "react-router-dom";
import SettingContext from '../contexts/setting';
function Top() {
const { state } = useContext(SettingContext);
return (
<div style={{ padding: '20px', backgroundColor: state.backgroundColor}}>
<h1 style={{ fontWeight: 'bold', fontSize: '32px' }}>トップ画面</h1>
<Link to="setting">設定画面</Link>
</div>
);
};
export default Top;
このファイルはトップ画面になります。Contextの色を取ってきて、この画面の背景色に設定します。
// pages/setting.js
import React, { useContext } from 'react';
import SettingContext from '../contexts/setting';
import { Link } from "react-router-dom";
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
function Setting() {
const { state, dispatch } = useContext(SettingContext);
function handlerRadioChange(e, color) {
dispatch(color);
};
return (
<div style={{ padding: '20px', display: 'flex', flexDirection: 'column' }}>
<h1 style={{ fontWeight: 'bold', fontSize: '32px' }}>設定画面</h1>
<Link to="/">top画面</Link>
<FormControl margin='normal'>
<FormLabel id="color-radio-buttons-group-label">背景色: {state.backgroundColor}</FormLabel>
<RadioGroup
aria-labelledby="color-radio-buttons-group-label"
defaultValue={state.backgroundColor}
name="radio-buttons-group"
row
>
<FormControlLabel value="white" control={<Radio />} label="white" onChange={e => handlerRadioChange(e, 'white')} />
<FormControlLabel value="lightgray" control={<Radio />} label="lightgray" onChange={e => handlerRadioChange(e, 'lightgray')} />
</RadioGroup>
</FormControl>
</div>
);
}
export default Setting;
このファイルは設定画面になります。ここではラジオボタンが押されたタイミング(onChange)で色をContextのstateにいれてます。
この時に発火する関数は初めにapp.jsで定義したreducerになるようにしてます。このreducerで実際にContextに背景色を入れる処理をしてます。
// contexts/setting.js
import { createContext } from 'react';
const SettingContext = createContext();
export default SettingContext;
このファイルはcreateContextでContextを定義して、名前を付けてます。
React hooksの一つで、親から子といった階層的にpropsで値を渡すものではなく、各コンポーネント間で値を共有できる機能です。
createContextでContext機能を作成し、Providerを用いて、値を渡します。
contextのstateを入れる時の処理を管理するものです。値を入れる前に調整などを行えます。
reducerを呼ぶための関数をdispatchといいます。
また、React hooksのContext機能を使用する時にreducerは省略することも可能です。
今回はReactのContext機能を使って、背景色の値を二つのコンポーネント間で共有してみました。まとめとして、処理の流れを簡単に振り返って終わりにしようと思います。
①SettingContextというContextを定義する
②設定画面で選択した色がSettingContextのstateに入る
③SettingContextに入っている色をトップ画面の背景色にセットする
以上です!
NEXTGATE LiSMOtechでは中小企業を中心にブランディング・WEBマーケティングを活用したWEB戦略を提供しています。
企業課題・問題に関するご相談、WEBサイト制作やグラフィックデザイン制作のクリエイティブに関するご相談やご質問、お見積りなどお気軽にお問い合わせください。
平日10:00〜19:00
© NEXTGATE LiSMOtech All rights reserved