Предоставление каждому компоненту в приложении Next.js пользовательского хука на pageLoad

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

import { useState, useEffect } from 'react';
import { useQuery } from '@apollo/client';
import { GET_AUTHED_USER } from '../utils/queries';
import { useAppContext } from '../context';

export const getCurrentUser = () => {
    const [isCompleted, setIsCompleted] = useState(false)

    const [state, setState] = useAppContext()

    const { data: authedUserData } = useQuery(GET_AUTHED_USER, {
        onCompleted: () => setIsCompleted(true)
    });

    useEffect(() => {
        Router.push('/home')
        if (isCompleted) {
            setState({
                currentUser: authedUserData?.getAuthedUser,
                isAuthed: true,
            });
        }
    }, [isCompleted]);

    return [state, setState];

_APP.js

import '../styles/reset.css'
import { AppWrapper } from '../context'
import { getCurrentUser } from '../hooks';


function MyApp({ Component, pageProps }) {
  const [state] = getCurrentUser()

  console.log(state) // TypeError: Invalid attempt to destructure non-iterable instance.

  return (
    <AppWrapper>
      <Component {...pageProps} />
    </AppWrapper>
  )
}


export default MyApp

хук работает в pages/index.js, но это означает, что я могу запустить его, только если будет достигнута конечная точка /.

<AppWrapper/> - это место, где изначально определяются все значения.

import { createContext, useContext, useState } from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { getCookie } from '../utils/functions';


const AppContext = createContext();

export function AppWrapper({ children }) {

  const URI = 'http://localhost:5000/graphql';

  const [state, setState] = useState({
    currentUser: null,
    isAuthed: false,
  });

  const httpLink = createHttpLink({
    uri: URI,
  });

  const authLink = setContext((_, { headers }) => {
    // get the authentication token from local storage if it exists
    const token = getCookie('JWT');
    // return the headers to the context so httpLink can read them
    return {
      headers: {
        ...headers,
        authorization: token ? token : '',
      }
    }
  });

  const client = new ApolloClient({
    cache: new InMemoryCache(),
    link: authLink.concat(httpLink)
  });


  return (
    <AppContext.Provider value={[state, setState]}>
      <ApolloProvider client={client}>
        {children}
      </ApolloProvider>
    </AppContext.Provider>
  );
}


export function useAppContext() {
  return useContext(AppContext);
}

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
0
25
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Интересный вопрос, вы хотите загружать эту часть кода только один раз при каждом обращении к браузеру?

Тогда место правильное. NextJs убедитесь, что когда у вас есть уникальное обращение к браузеру, он запускается _app.js, но только один раз, после чего он переходит в режим одностраничного приложения.

После вышеприведенного факта на самом деле то, выполняется ли часть кода только один раз, два или несколько раз, в основном зависит от того, сколько раз он обнаруживает «изменение».

  useEffect(() => {
     // run
  }, [condition])

Если условие изменится, он запустится снова. Однако, если условие не изменится, а будет перемонтирован весь кусок, он снова запустится. Вы должны рассмотреть оба факта здесь.

Короче говоря, если вам нужно запустить его для изменения маршрута, сделайте condition === route.name. Совет, попробуйте сначала поработать с одностраничным приложением, а потом работать с уникальной фичей nextJS, иначе будет очень сложно найти ответ.

Другие вопросы по теме