コードは下記にアップ
github
https://github.com/umema4/react16_webpack4_typescript
reacr-router redirectサンプルの適用
npm install --save react-router-dom @types/react-router-dom react-hooks-global-state
まずはRedirectのサンプルをコードに適用する
https://reacttraining.com/react-router/web/example/auth-workflow
既存コードでApp componentとしていたものをCounterにrename。
protectedなcomponentで表示できるようにする
<PrivateRoute path="/protected">
<Counter />
</PrivateRoute>
typescriptのエラーが出るので諸々直す
callbackの型定義
- authenticate(cb) {
+ authenticate(cb: () => void) {
fakeAuth.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
引数でchildrenを渡す
+type PrivateRouteProps = {
+ children: React.ReactNode;
+ path: string;
+};
+function PrivateRoute({ children, path }: PrivateRouteProps) {
-function PrivateRoute({ children, ...rest }) {
"message": "Property 'from' does not exist on type '{} | { from: { pathname: string; }; }'.",
+ const { from } = (location.state as any) || {
+ from: { pathname: '/' },
+ };
- const { from } = location.state || { from: { pathname: '/' } };
react-hooks-global-state reducerパターンの適用
store.tsxを作成しそこでcreateStoreを実装
Actionのtypeを定義
isAuthenticatedをglobalで持つ
const initialState = {
isAuthenticated: false,
};
signinが呼ばれたらstateを変更して返す
case 'signin': {
return {
...state,
isAuthenticated: true,
};
}
fakeAuthの処理をglobalStoreの処理に置き換える
dispatchの処理のあとにcallbackで扱っていた処理を呼びたかったのでasyncつける
const signin = async () => dispatch({ type: 'signin' });
これでloginの処理がthenで繋げられる
const login = () => {
signin().then(() => {
history.replace(from);
});
};
global stateを参照する場所はuseGlobalStateでとってくる
const [isAuthenticated] = useGlobalState('isAuthenticated');
store参照しているAuthButtonとLoginPageのファイルを分けるリファクタリングをして
ちゃんと動作することを確認
これで置き換え完了。
webpack dev serverのfallback
/publicとかを表示いるところでリロードがかかるとエラーが発生する
Cannot GET /public
開発効率が悪いのでwebpack.config.jsでhistoryApiFallbackを設定
historyApiFallback: true,