Обмен данными API с другими компонентами с помощью React Hook, NO REDUX - PullRequest
1 голос
/ 12 февраля 2020

Я экспериментирую с хуками без какого-либо инструмента управления состоянием (например, Redux), чтобы получить такое же поведение / структуру, какую я мог бы иметь, используя традиционную структуру классов + redux.

Обычно с базовым кодом класса я бы:

  • Отправка ComponentDidMount для вызова API
  • Использование действий и редукторов для хранения данных в Redux
  • Поделиться данные для любого компонента, который я хочу, используя mapStateToProps

И здесь, где проблема заключается в использовании хуков без Redux: «Поделиться данными с любым компонентом».

В следующем примере показано, как я делю состояния между компонентами с помощью хуков:

// app. js

import React, { useReducer } from 'react'
import { BrowserRouter } from 'react-router-dom'
import Routes from '../../routes'
import Header from '../Shared/Header'
import Footer from '../Shared/Footer'

export const AppContext = React.createContext();

// Set up Initial State
const initialState = {
  userType: '',
};

function reducer(state, action) {
  switch (action.type) {
    case 'USER_PROFILE_TYPE':
      return {
        userType: action.data === 'Student' ? true : false
      };
    default:
      return initialState;
  }
}

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <BrowserRouter>
      <AppContext.Provider value={{ state, dispatch }}>
        <Header userType={state.userType} />
        <Routes />
        <Footer />
      </AppContext.Provider>
    </BrowserRouter>
  )
}

export default App

// profile. js

import React, { useEffect, useState, useContext} from 'react'
import { URLS } from '../../../constants'
import ProfileDeleteButton from './ProfileDeleteButton'
import DialogDelete from './DialogDelete'
import api from '../../../helpers/API';

// Import Context
import { AppContext } from '../../Core'

const Profile = props => {

  // Share userType State
  const {state, dispatch} = useContext(AppContext);
  const userType = type => {
    dispatch({ type: 'USER_PROFILE_TYPE', data: type }); <--- Here the action to call the reducer in the App.js file
  };

  // Profile API call
  const [ profileData, setProfileData ] = useState({});

  useEffect(() => {
    fetchUserProfile()
  }, [])

  const fetchUserProfile = async () => {
    try {
      const data = await api
        .get(URLS.PROFILE);
      const userAttributes = data.data.data.attributes;
      userType(userAttributes.type) <--- here I am passing the api response
    }
    catch ({ response }) {
      console.log('THIS IS THE RESPONSE ==> ', response.data.errors);
    }
  }
etc.... not important what's happening after this...

сейчас, единственный способ увидеть значение userType - это передать его как опору компоненту <Header />.

// app. js

  <BrowserRouter>
    <AppContext.Provider value={{ state, dispatch }}>
      <Header userType={state.userType} /> <--passing here the userType as prop
      <Routes />
      <Footer />
    </AppContext.Provider>
  </BrowserRouter>

Допустим, я хочу передать это значение userType детям <Routes />. Вот пример:

<AppContext.Provider value={{ state, dispatch }}>
   <Routes userType={state.userType} />
</AppContext.Provider>

and then, inside <Routes /> ...

const Routes = () => 
  <Switch>
     <PrivateRoute exact path="/courses" component={Courses} userType={state.userType} /> 
  </Switch>

Мне не нравится. Это не чистый, устойчивый или масштабируемый. Любые предложения о том, как сделать кодовую базу лучше?

Большое спасибо Джо

1 Ответ

0 голосов
/ 13 февраля 2020

Вам не нужно передавать состояние в качестве опоры каждому компоненту. Используя контекст, вы можете получить доступ к правильности состояния в вашем редукторе внутри каждого дочернего компонента родительского провайдера. Как вы уже сделали в профиле. js

 const {state, dispatch} = useContext(AppContext);

Свойство State здесь содержит свойство состояния в редукторе. Таким образом, вы можете получить к нему доступ state.userType

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...