1

useContext() と useReducer() を使用して、redux を取り除いて別のパッケージを保存し、状態管理の新しい方法を学びたいと考えています。ブロッカーに当たりました。

レデューサーがペイロードを更新した後のログイン ページ。以下のスクリーンショットで確認できます。Context.Provider と reducer の値が更新されていることがわかりますが、console.log('context') を実行すると、まだ初期値が取得されます。

コンポーネント間で更新されたペイロードを共有したいのですが、これをネイティブに行う唯一の方法は localStorage ですか? または、概念的に何かが欠けていますか。

前もって感謝します。

これが AuthProvider の Context.Provider です - コンテキストも更新されますが、/dashboard または dashboard.tsx に移動すると、コンテキストは initialState に戻ります。

useReducer の状態が更新されましたが、これをログインとダッシュボードの間で共有するにはどうすればよいですか

ここに私のApp.tsxがあります

import React from 'react'
import { hot } from 'react-hot-loader/root'
import { AuthProvider } from '~context/authContext'
import { ThemeProvider } from 'styled-components'
import { StoreProvider } from 'easy-peasy'
import theme from '~styles/theme'
import { GlobalStyles } from '~styles/index'
import { Routes } from '~root/routes'
import { store } from '~store/index'

const App = () => (
  <ThemeProvider theme={theme}>
    <StoreProvider store={store}>
      <GlobalStyles />
      <AuthProvider>
        <Routes />
      </AuthProvider>
    </StoreProvider>
  </ThemeProvider>
)

export default hot(App)

これが私のAuthProviderです:-

import React, { FC, createContext, useReducer } from 'react'
import authReducer, { authInitialState } from '~reducers/authReducer'
import { TState, IAuthProvider } from './types'

export const AuthContext = createContext<[TState, React.Dispatch<any>]>(undefined)

export const AuthProvider: FC<IAuthProvider> = props => {
  const authData = useReducer(authReducer, authInitialState)
  return <AuthContext.Provider value={authData}>{props.children}</AuthContext.Provider>
}

export const AuthConsumer = AuthContext.Consumer

これが私のauthReducerです:-

import { IAuthInitialState, IState, IReducerAction } from './types'
import { actions } from './actions'

export const authInitialState: IAuthInitialState = {
  accessToken: null,
  isAuthed: false,
  error: false,
}

const authReducer = (state: IState, action: IReducerAction) => {
  switch (action.type) {
    case actions.SET_ACCESS_TOKEN:
      return {
        ...state,
        ...action.payload,
      }
    case actions.RESET_ACCESS_TOKEN:
      return {
        ...authInitialState,
      }
    case actions.ERROR:
      return {
        ...authInitialState,
        ...action.payload,
      }
    default:
      throw new Error('Unexpected action')
  }
}

export default authReducer

ここに私のログインページがあります:-

import React, { FC, useEffect, useContext } from 'react'
import { useHistory, useLocation } from 'react-router-dom'
import { Container, Col } from 'react-bootstrap'
import { useStoreActions, useStoreState } from '~store/hooks'
import { RedirectState } from '~root/routes/privateRoute'
import { StyledRow } from './styles'
import { AuthContext } from '~context/authContext'
import { getAccessToken } from '~utilities/index'

const Login: FC = () => {
  const history = useHistory()
  const { state } = useLocation<RedirectState>()
  const { isAuthenticated } = useStoreState(({ user }) => user)
  const [{ setUserModel }, { setSideNavModel }] = useStoreActions(({ user, sideNav }) => [user, sideNav])
  const [context, dispatch] = useContext(AuthContext)

  useEffect(() => {
    setSideNavModel({ title: 'login', activeChild: 'login' })
    const token = getAccessToken()

    const authData = {
      isAuthed: true,
      accessToken: token,
      time: Date(),
    }

    if (token) {
      dispatch({
        type: 'update',
        payload: authData,
      })

      localStorage.setItem('authedData', JSON.stringify(authData))
    }
  }, [])

  return (
    <Container id="page-container">
      <StyledRow className="justify-content-md-center">
        <Col md="auto"></Col>
      </StyledRow>
    </Container>
  )
}

export default Login
4

0 に答える 0