Контекст API не передает данные должным образом - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь изучить хиты React, и у меня есть некоторые проблемы с тем, как провайдеры передают свои данные моим компонентам.

У меня есть AuthContex, UsersContext, LanguagesContext и WordsContext.

ReactDOM.render(
  <React.StrictMode>
    <AuthProvider>
      <UsersProvider>
        <LanguagesProvider>
          <WordsProvider>
            <App />
          </WordsProvider>
        </LanguagesProvider>
      </UsersProvider>
    </AuthProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

AuthContext и UsersContext в порядке.

WordsContext правильно возвращает свое состояние, но выдает «TypeError: getWord не является функцией», когда я пытаюсь вызвать getWord ().

LanguagesContext возвращает «неопределенное», когда я пытаюсь использовать «язык», несмотря на тот факт, что его значение установлено в «Engli sh», а также выдает «TypeError» при вызове getLanguage ().

Чтобы сделать это более наглядным:

export const Languages = () => {

  const { getLanguage, language } = useContext(LanguagesContext)
  const { getWord, word } = useContext(WordsContext)
  const { getUser, user } = useContext(UsersContext)

  const token = localStorage.getItem('token')
  const userId = localStorage.getItem('id')

  useEffect(() => {
    getUser(token, userId) // Works fine
    getWord(token, 1) // throws TypeError: getWord is not a function
    getLanguage(token, 1) // throws TypeError: getLanguage is not a function
  }, []);

  return (
    <div>
      {user ? user.name : null} {/* Works fine */} 

      {language} {/* Returns undefined despite being set to "English" in state */} 

      {word} {/* Returns state value but getWord() throws an error */} 
    </div>
  )
}

Я предполагаю, что функции выдают ошибку, потому что они оба возвращаются как "неопределенные" из контекста, но я абсолютно не знаю, что может вызвать эту проблему .

WordsContext:

const initialState = {
  word: 'Example',
  errors: null
}

export const WordsContext = createContext(initialState)

const port = 'http://127.0.0.1:8000'

const version = 'v1'

export const WordsProvider = ({ children }) => {
  const [state, dispatch] = useReducer(WordsReducer, initialState)

  async function getWord(token, word_id) {
    const config = {
      headers: {
        'Content-Type': 'application/json',
        "Authorization": token
      }
    }

    try {
      const res = await axios.get(`${port}/${version}/words/${word_id}`, config)

      dispatch({
        type: GET_WORD,
        payload: res.data
      })
    } catch (err) {
      dispatch({
        type: FAIL,
        payload: err
      })
    }
  }

  return (<LanguagesContext.Provider value={{
    word: state.word,
    erros: state.errors,
    getWord,
  }}>
    {children}
  </LanguagesContext.Provider>)
}

LanguagesContext:

const initialState = {
  language: 'English',
  errors: null
}

export const LanguagesContext = createContext(initialState)

const port = 'http://127.0.0.1:8000'

const version = 'v1'

export const LanguagesProvider = ({ children }) => {
  const [state, dispatch] = useReducer(LanguagesReducer, initialState)

  async function getLanguage(token, languageId) {
    const config = {
      headers: {
        'Content-Type': 'application/json',
        "Authorization": token
      }
    }

    try {
      const res = await axios.get(`${port}/${version}/languages/${languageId}`, config)

      dispatch({
        type: GET_LANGUAGE,
        payload: res.data
      })
    } catch (err) {
      dispatch({
        type: FAIL,
        payload: err
      })
    }
  }

  return (<LanguagesContext.Provider value={{
    language: state.language,
    erros: state.errors,
    getLanguage,
  }}>
    {children}
  </LanguagesContext.Provider>)
}

1 Ответ

1 голос
/ 24 апреля 2020

Вы по ошибке использовали LanguagesContext.Provider вместо WordsContext.Provider в вашем WordsProvider, что вызывает конфликт с LanguagesContext, и из-за этого WordsContext также не работает

export const WordsProvider = ({ children }) => {
  const [state, dispatch] = useReducer(WordsReducer, initialState)

  async function getWord(token, word_id) {
    const config = {
      headers: {
        'Content-Type': 'application/json',
        "Authorization": token
      }
    }

    try {
      const res = await axios.get(`${port}/${version}/words/${word_id}`, config)

      dispatch({
        type: GET_WORD,
        payload: res.data
      })
    } catch (err) {
      dispatch({
        type: FAIL,
        payload: err
      })
    }
  }

  return (
   <WordsContext.Provider value={{
    word: state.word,
    erros: state.errors,
    getWord,
  }}>
    {children}
  </WordsContext.Provider>
  )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...