Дублируется при изменении Context

Решил использовать контексты в проекте, но не совсем с ними знаком, но выбор пал на них из-за того, что потом будет разрабатываться ещё приложение на React Native и чтобы было проще перенести всё. Проблема в том, что плохо составленная структура для работы с API и при изменение контекста в консоли хаос - запросы отправляются без остановки.

Вот примеры кода:

test.js

import React from 'react';
import { getCurrentShedule } from '../../model/actions';

export const Test = () => {
    console.log(getCurrentShedule());

    return (
        <div>Text</div>
    );
};

/model/actions.js

import React from 'react';
import axios from 'axios';
import { DataContext } from "./context";

axios.defaults.baseURL = "https://test.site/api";
axios.defaults.headers.common['Content-Type'] = 'application/json';
axios.defaults.headers.common['Authorization'] = "token";
// axios.defaults.headers.common['Authorization'] = "Bearer "+ res.data.access_token;

const JWT_TOKEN = () => {
    const { Data, setData } = React.useContext(DataContext);

    axios.post(`${axios.defaults.baseURL}/auth/login`, {
        phone: "79999999999",
        password: "00000"
    }).then(res => {
        setData({
            ...Data,
            auth: {
                jwt: res.data.access_token
            }
        });
    });
    console.log("Data", Data);
};


export const getCurrentShedule = () => {
    JWT_TOKEN();
    axios.get(`${axios.defaults.baseURL}/periods`).then(res => {
        console.log("res", res.data);
    });
};

После запуска JWT_TOKEN() в консоли видно, что запросы отправляются без остановки и не останавливается совсем. Если я убираю изменение в setData(), то запрос отправляется только 1 раз...

Ещё пробовал в getCurrentShedule() получить Context, но выдает ошибку React Hook "React.useContext" is called in function "getCurrentShedule" which is neither a React function component or a custom React Hook function


Ответы (1 шт):

Автор решения: Konstantin Modin

Не совсем правильно вызывать hook здесь:

const JWT_TOKEN = () => {
    const { Data, setData } = React.useContext(DataContext);

лучше передать контекст параметром:

test.js:

import React, { useEffect, useContext } from "react";
import { getCurrentShedule } from "../../model/actions";
import { DataContext } from "./context"; // update path

export const Test = () => {
  const { Data, setData } = useContext(DataContext);

  useEffect(() => {
    console.log(getCurrentShedule(Data, setData));
  }, []);

  return <div>Text</div>;
};

actions.js:

import React from "react";
import axios from "axios";

axios.defaults.baseURL = "https://test.site/api";
axios.defaults.headers.common["Content-Type"] = "application/json";
axios.defaults.headers.common["Authorization"] = "token";
// axios.defaults.headers.common['Authorization'] = "Bearer "+ 
res.data.access_token;

const JWT_TOKEN = (Data, setData) => {
  axios
    .post(`${axios.defaults.baseURL}/auth/login`, {
      phone: "79999999999",
      password: "00000",
    })
    .then((res) => {
      setData({
        ...Data,
        auth: {
          jwt: res.data.access_token,
        },
      });
    });
  console.log("Data", Data);
};

export const getCurrentShedule = (Data, setData) => {
  JWT_TOKEN(Data, setData);
  axios.get(`${axios.defaults.baseURL}/periods`).then((res) => {
    console.log("res", res.data);
  });
};
→ Ссылка