Redux が理解できず実際にサンプルページを作ってみた
日付:2021-12-20更新日:2021-12-20
目次
Redux 便利なのはわかるけど仕組みがイマイチわかってない気がする~
React でデータを使いまわすには、props や Context を使えばいいのですが、どこからでもアクセス可能でデータを一元管理できる Redux 。。
これで全ていける!という暴力的な考え方は置いといて、便利なのはわかるけどイマイチ仕組みが分かりづらい…と思ったので、超かんたんなサンプルページを作ることにしました。
インプットボックスに値を入れてボタンを押すと、テキストまたはリンク先が変更されるってだけの超シンプルなページです。
やったこと
ステップ1:React プロジェクトを作る
当たり前ですけどね…
npx create-react-app my-app
ステップ2:reactとreact-reduxをインストール
作成したプロジェクトディレクトリ(my-app)に移動してreactとreact-reduxをインストール。
ReactでReduxを利用するために二つ必要。
npm install redux react-redux
ステップ3:Store(データの保管場所)とReducer(データの更新担当)の作成
作った場所は、/store/index.js です。
Storeの値(初期値)は、リンク先のURL(linkUrl)とリンクテキスト(linkText)の二つを State に設定。
どのタイミングでデータを書き換えるのかを担当するReducerは、Action から受け取ったメッセージにあったデータを更新するように switch で記載していきます。
Git sauce
import { createStore } from "redux";
// 初期State
const initialState = {
linkUrl: 'https://www.yahoo.co.jp/',
linkText: 'Yahoo',
}
// Reducer処理 どのタイミングでデータを書き換えるのか
const reducer = (state = initialState, action) => {
switch (action.type) {
//action からメッセージ CHANGE_LINK_URL を受け取ったら
case 'CHANGE_LINK_URL': {
// initialState の linkUrl を action.payload.value に変更
return {...state,linkUrl:action.payload.value}
}
case 'CHANGE_LINK_TEXT': {
return {...state,linkText:action.payload.value}
}
case 'CHANGE_LINK_BOTH': {
return {...state,linkText:action.payload.text,linkUrl:action.payload.url}
}
default: {
return state
}
}
}
const store = createStore(reducer);
export default store;
ステップ4:Reducer にメッセージと指示を与える Action の作成
作った場所は、/actions/actions.js です。
アクションは、ボタンの数と同じ3つ。
リンク先のURLを変更する、リンクテキストを変更する、リンクテキストとURL両方を変更するの3つを記載。
Git sauce
// ./redux/AppActions.js
/**
* Action type
*/
const CHANGE_LINK_URL = "CHANGE_LINK_URL";
const CHANGE_LINK_TEXT = "CHANGE_LINK_TEXT";
const CHANGE_LINK_BOTH = "CHANGE_LINK_BOTH";
/**
* Action creator
*/
export const changeLinkUrl = (value) => ({
type: CHANGE_LINK_URL,
payload: {
value,
},
});
export const changeLinkText = (value) => ({
type: CHANGE_LINK_TEXT,
payload: {
value,
},
});
export const changeLinkBoth = (text,url) => ({
type: CHANGE_LINK_BOTH,
payload: {
text,
url
},
});
ステップ5:Provider でコンテンツを括る
Redux の storeデータをどこでも使いまわせるようにするには Provider でコンポーネントをくくる必要があります。
その前に、①React-ReduxのProviderをインポートと②新しく作ったstoreをインポートをしています。
↓index.js Git sauce
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
//①React-ReduxのProviderをインポート
import { Provider } from "react-redux";
//②新しく作ったstoreをインポート
import store from "./store/index";
//④Provider でくくる。
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
ステップ6:コンポーネントファイルを作る
/components/LinkBlock.js にコンポーネントとして表示部分を分けました。
store から値を取得するために useSelector、Reducer にメッセージを送る為に useDispatch を使ったので、それぞれ import しています。
Action の命令も import しています。
そして、useDispatch使います宣言を18行目でしています。
Git sauce
import { React, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
changeLinkUrl,
changeLinkText,
changeLinkBoth,
} from "../actions/actions";
import './LinkBlock.css';
function LinkBlock() {
//input の値
const [inputLinkText, setInputLinkText] = useState("");
const [inputLinkURL, setInputLinkURL] = useState("");
//store から値を取得
const linkUrl = useSelector((state) => state.linkUrl);
const linkText = useSelector((state) => state.linkText);
//useDispatch使います宣言
const dispatch = useDispatch();
//命令
const changeURL = () => {
if (inputLinkURL) {
dispatch(changeLinkUrl(inputLinkURL));
} else {
alert("リンク先を入れてね");
}
};
const changeText = () => {
if (inputLinkText) {
dispatch(changeLinkText(inputLinkText));
} else {
alert("テキストを入れてね");
}
};
const changeBoth = () => {
if (inputLinkURL && inputLinkText) {
dispatch(changeLinkBoth(inputLinkText, inputLinkURL));
} else {
alert("値が足りません");
}
};
return (
<div className='Contents'>
<p>
<a href={linkUrl}>{linkText}</a>
</p>
<form action="" className="Form">
<div className="Form__inputs">
<div className="Form__input">
<label htmlFor="linktext">リンクテキストを入れてください</label>
<input
id="linktext"
type="text"
value={inputLinkText}
onChange={({ target: { value } }) => setInputLinkText(value)}
placeholder="Link Text"
/>
</div>
<div className="Form__input">
<label htmlFor="linkulr">リンクURLを入れてください</label>
<input
type="linkulr"
value={inputLinkURL}
onChange={({ target: { value } }) => setInputLinkURL(value)}
placeholder="Link URL"
/>
</div>
</div>
<div className="Form__btns">
<button type="button" onClick={changeURL}>
リンクを変更
</button>
<button type="button" onClick={changeText}>
テキストを変更
</button>
<button type="button" onClick={changeBoth}>
リンクとテキストを変更
</button>
</div>
</form>
</div>
);
}
export default LinkBlock;
ステップ7:コンポーネントファイルを読み込む
App.js に作ったコンポーネントを呼び込みます。
Git sauce
import './App.css';
//コンポーネントを呼ぶだけ。
import LinkBlock from "./components/LinkBlock";
function App() {
return (
<div className="App">
<LinkBlock></LinkBlock>
</div>
);
}
export default App;
出来た!ので仕組みはわかったかな
今回、参考にしたページはReac初心者でも読めば必ずわかるReactのRedux講座です。
ほぼそのまんま書いた感じですが、やりたいことが数のカウントじゃなかったので、その辺り「えーえーえーーーっ」って言いながら変更してましたw。
サラッと出来たふうですけど、つまらないところでジタバタしてましたね
ははは σ(*´∀`照)
Redux を使う場面を考えると割とおおきなサイトでデータの取り回しをするという感じなので、こんな小さなサンプルページではまだまだイメージが遠いけど、基本が分かればやっていることが分かるのでまぁ一歩前進です!とこれからも前向きに頑張ります!