Почему я не могу использовать useContext здесь?

Суть моего вопроса заключается в том, чтобы узнать почему внутри Todos.tsx я могу использовать useContext, а внутри TodosPage.tsx не могу. Выбрасывает 2 ошибки. Если что, то я работаю на 18 версии и использую бутстрап.

введите сюда описание изображения

Вот необходимые файлы:

App.tsx

import React from 'react'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import Alert from './components/Alert'
import Header from './components/Header'
import AlertState from './context/alert/AlertState'
import FirebaseState from './context/firebase/FirebaseState'
import { routes } from './routes/routes'

export default function App() {

  return (
      <AlertState>
        <BrowserRouter>
          <Header/>
          <div className={'container pt-4'}>
            <Alert/>
            <FirebaseState>
            <Routes>
              {
                routes.map((route) => 
                  <Route path={route.path} element={route.elem} key={route.path}></Route>
                )
              }
            </Routes>
            </FirebaseState>
          </div>
        </BrowserRouter>
      </AlertState>
  )
}

TodosPage.tsx

import React from 'react'
import Form from '../components/Form';
import Todos from '../components/Todos';
import { FirebaseContext } from '../context/firebase/firebaseContext';
import FirebaseState from '../context/firebase/FirebaseState';

const TodosPage = () => {

  //! ВОТ ИЗ-ЗА ЧЕГО ВОЗНИКАЕТ ОШИБКА
  // const {firebaseState} = React.useContext(FirebaseContext)
  // console.log(firebaseState)

  return (
    <div className='container'>
        <h1 className='display-4 fw-bold text-decoration-underline'>Main</h1>
        <Form/>
        <hr/>
        <p className='font-monospace fw-700 fs-14 text-center mt-5 text-decoration-underline'>Your Books</p>
        <Todos/> 
  </div>
  )
}

export default TodosPage;

Todos.tsx (Здесь всё работает нормально)

import React from 'react'
import { FirebaseContext } from '../context/firebase/firebaseContext';
import { ITodo } from '../types/ITodo'

const Todos = () => {

  //! ЗДЕСЬ ПРОБЛУЕМ НЕТ, ЛОГИ ПОКАЗЫВАЮТ ОТВЕТ
  const {firebaseState} = React.useContext(FirebaseContext);
  console.log(firebaseState);

  return (
    <ol className="list-group list-group-numbered mb-5">
      {/* {
        todos.map(todo => 
          <li className="list-group-item d-flex justify-content-between align-items-start">
            <div className="ms-2 me-auto">
              <div className="fw-bold">{todo.title} <span className='fw-light fs-10 font-monospace'> - {todo.time} min.</span></div>
              {todo.additional}
            </div>
            <div className='d-flex flex-column'>
              <div className='d-flex justify-content-end mb-2'>
                <span className="badge bg-primary rounded-pill">{todo.potency}</span>
              </div>
              <button type="button" className="btn btn-danger">&times;</button>
            </div>
          </li>
        )
      } */}
    </ol>
  )
}

export default Todos

firebaseContext.ts

import React from 'react'
import { IFirebase } from './firebaseTypes';

interface IFirebaseContext {
    showLoader: () => void;
    addTodo: () => Promise<void>;
    fetchTodos: () => Promise<void>;
    removeTodo: (id: number) => Promise<void>;
    firebaseState: IFirebase;
}

export const FirebaseContext = React.createContext<IFirebaseContext>({} as IFirebaseContext);

firebaseReducer.ts

import { IFirebase, IFirebaseAction } from "./firebaseTypes"

export const firebaseReducer = (state: IFirebase, action: IFirebaseAction): IFirebase => {
    switch(action.type) {
        case 'SHOW_LOADER':
            return {...state, loading: true}
        case 'ADD_TODO': 
            return {...state, todos: [...state.todos, ...(action.payload ? action.payload.todos : [])]}
        case 'DELETE_NOTE': 
            return {...state, todos: state.todos.filter(todo => todo.id !== action.id)}
        case 'FETCH_NOTES': 
            return {...state, todos: action.payload?.todos!}
        default: 
            return state
    }
}

firebaseTypes.ts

import { ITodo } from "../../types/ITodo";

export type TFirebaseActionType = 'HIDE_ALERT' | 'SHOW_ALERT' | 'SHOW_LOADER' | 'ADD_TODO' | 'FETCH_NOTES' | 'DELETE_NOTE';

export interface IFirebase {
    todos: ITodo[];
    loading: boolean;
}

export interface IFirebaseAction {
    type: TFirebaseActionType;
    payload?: IFirebase;
    id?: number;
}

FireabseState.tsx (Последнее)

import axios from 'axios';
import React from 'react'
import { ITodo } from '../../types/ITodo';
import { FirebaseContext } from './firebaseContext';
import { firebaseReducer } from './firebaseReducer';


interface FirebaseStateProps {
  children: React.ReactNode | React.ReactChild;
}

const URL: string = process.env.REACT_APP_DB_URL!;

const FirebaseState: React.FC<FirebaseStateProps> = ({children}) => {

  const [state, dispatch] = React.useReducer(firebaseReducer, {todos: [], loading: false})

  const showLoader = () => {
    dispatch({type: 'SHOW_LOADER', payload: {...state}})
  }

  const fetchTodos = async () => {
    showLoader();
    const result = await axios.get(`${URL}/todos.json`);
    console.log('fetchNotes', result.data);
    dispatch({type: 'FETCH_NOTES', payload: {...state, todos: result.data}})
  }

  const addTodo = async () => {
    const todo: ITodo = {
      id: Date.now(),
      completed: false,
      additional: 'New todo',
      potency: 3,
      time: 25,
      title: 'Fushhh'
    }

    const result = await axios.post(`${URL}/todos.json`, todo);
    console.log('addTodo', result.data);
    dispatch({type: 'DELETE_NOTE', payload: {...state, todos: [...state.todos, result.data]}})
  }

  const removeTodo = async (id: number) => {
    await axios.delete(`${URL}/notes/${id}.json`);
    dispatch({type: 'DELETE_NOTE', payload: {...state}, id})
  }


  return (
      <FirebaseContext.Provider value={{firebaseState: state, showLoader, addTodo, removeTodo, fetchTodos}}>
        {children}
      </FirebaseContext.Provider>
  )
}

export default FirebaseState

Здесь firebase не имеет прямо принципиального влияния, т.к. я пробовал и без него так делать - безуспешно. Я понимаю, что вопрос довольно большой, но я прошу мне помочь, потому что я и сам потратил много времени как решить этот вопрос. Мне кажется, что другим новичкам, как и мне, такой вопрос пойдет только на пользу. Если потребуется доп. информация - пишите.


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