Установите данные в React Context из асинхронного вызова API - PullRequest
1 голос
/ 02 октября 2019

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

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

Вот как я пытаюсь установить мои данные контекста

import React, {useState,useEffect} from "react";
import {callAffiliateApi} from "./services/affiliateService/transactionContext";

export const AffiliateContext = React.createContext("Raaaaaaaaaaaa");

export const AffiliateProvider  = ({children}) => {

  const [data, setData] = useState(null);
  useEffect(()=> {
    async function fetchData() {
      const newText = await callAffiliateApi();
      setData(newText)
    };fetchData()
  },[])

  console.log("Data in the context", data);
  if(data != null){
    return (
      <AffiliateContext.Provider value={data}>
        {children}
      </AffiliateContext.Provider>
    )}
  else {
    return (
      <AffiliateContext.Provider value={"Loading..."}>
        {children}
      </AffiliateContext.Provider>)
  }

}


А вот как я пытаюсь получить к ним доступ в дочернем компоненте

import {AffiliateContext} from "../../../../AffiliateContext";

class Profile extends Component {


  constructor(props) {
    super(props);
    this.state = {
      text: this.props.text,
      user: this.props.user,

    }

  }

  render() {
    return (
    <AffiliateContext.Consumer>
      {data =>
        <div>
        {data}
      </div>}
    </AffiliateContext.Consumer>
      )
  }
}
export default Profile;

Однако единственное, что отображается на странице, это "Raaaaaaa", значение по умолчанию для компонента. Как заставить дочерний компонент ждать, пока данные не завершат выборку из запроса API?

Ответы [ 2 ]

1 голос
/ 02 октября 2019

попробуйте использовать useContext его очиститель и постарайтесь не использовать асинхронность внутри useEffect!

связанные с ними вопросы

import React, { useState,useEffect,useContext } from "react";
import { callAffiliateApi } from "./services/affiliateService/transactionContext";

const Context = React.createContext({});
const AffiliateContext = init => useContext(Context);

export const AffiliateProvider  = ({children}) => {

  const [data, setData] = useState(null);
  const [loading,setLoading]=useState(false);

  const getAffiliates = async ()=>{
      setLoading(true)
      const newText = await callAffiliateApi();
      setData(newText)
      setLoading(false)
  }
  useEffect(()=> {
    getAffiliates()
  },[])


    return (
      <AffiliateContext.Provider value={{loading,list:data}}>
        {children}
      </AffiliateContext.Provider>
    )
}
0 голосов
/ 02 октября 2019

Я думаю, что это хороший вариант использования для useAsyncReducer hook

import createActions from './createActions';
import useAsyncReducer from '../../hooks/useAsyncReducer';
import reducer, { initialState } from './reducer';

export const CounterContext = React.createContext();

export const CounterProvider = ({ children }) => {
  const [state, dispatch] = useAsyncReducer(reducer, initialState);
  const actions = createActions(dispatch);

  return (
    <CounterContext.Provider value={[state, actions]}>
      {children}
    </CounterContext.Provider>
  );
};

Взгляните на эту удобную статью, которая более подробно описана.

...