ある日
![]()
![]()
![]()
お勉強用react製web appをいじっていたら TypeError: _useSelector is undefined というエラーが! ![]()
しかし普通にbuildは通る
そしてググっても出てこない(気がする) ![]()
↓ばーじょん↓
react@16.12.0react-redux@7.1.3redux@4.0.5reselect@4.0.0
こんなコード書いてた
![]()
![]()
![]()
// src/containers/App.tsx
const appSelector = createSelector(
(state: { init: AppState }) => state.init,
init => init
)
export const AppContainer: React.FC = () => {
const dispatch = useDispatch()
const { loading, loaded, error } = useSelector(appSelector)
const loadDispatcher = (): void => {
dispatch(initOp())
}
return (
<AppView
loading={loading}
loaded={loaded}
error={error}
loadDispatcher={loadDispatcher}
/>
)
}
// src/reducers/index.ts
export default combineReducers({
app: appReducer,
todos: todoReducer,
visibilityFilter: visibilityFilterReducer,
})
// src/reducers/app.ts
export const appReducer = reducerWithInitialState({
loaded: false,
loading: false,
error: null,
} as AppState)
.cases(...
と、こうやって書けば一目瞭然で(実際はファイルが別れているのでそこそこ時間を取られた)
-
appSelector()ではinitからAppStateを取得しようとしている -
combineReducers()ではappにappReducerとして結合されている
このため、上記エラーが出たようだった。
実際にはuseSelector()の引数にダミーの(() => true的な)selectorを使うなどしてエラー原因の特定を行った。
以上よりappSelectorを以下のように修正することでエラーは解消した。
// reselect使っている理由は特に無いです(使ってみたかった)
// この程度ならワンライナーで
// const appSelector = ({ app }: { app: AppState }): AppState => app
// の方が分かりやすいですね
const appSelector = createSelector(
(state: { app: AppState }) => state.app,
app => app
)
所感
![]()
![]()
![]()
reducerが無いと_useSelector()が未定義状態になるのかーというのが一番の収穫![]()
当初InitStateとして定義していたが名前的に微妙だな思いAppStateに変えたのだが、この修正が一部漏れていた![]()
selector周りでtypescriptの型チェックが微妙な感じになってしまうのは予想外で、もう少し丁寧に書くべきだったと反省![]()
