Реакция useState () & useContext () - TypeError: setState не является функцией - Что я делаю не так? - PullRequest
1 голос
/ 01 мая 2020

У меня есть несколько функциональных компонентов React, которые я хотел бы поделиться состоянием. В этом примере две кнопки переключения, которые условно отображают / скрывают панель поиска и панель навигации.

- Решение, основанное на принятом ответе, внизу -

Я совершенно новичок в useContext() и продолжаю сталкиваться со следующей ошибкой в ​​консоли: Uncaught TypeError: setSearchbarToggle is not a function Это касается обеих кнопок.

Ниже у меня отфильтрованный пример кода. Это просто для примера я использую состояния в одном файле. В реальной жизни я бы повторно использовал состояния в нескольких функциональных компонентах.

Это мой header.js

import React, { useState, useContext } from "react"
import "./header.sass"
import { Context } from "./HeaderContext"

export const Header = () => {

  const headerContext = useContext(Context)
  const { navbarToggle, setNavbarToggle, searchbarToggle, setSearchbarToggle } = headerContext

  return (
    <React.Fragment>
      <div className={"sticky-top"}>

        <button onClick={ () => setNavbarToggle( !navbarToggle )}> Toggle Menu </button>
        <button onClick={ () => setSearchbarToggle( !searchbarToggle )}> Toggle Search </button>

        {navbarToggle && <h3>Menu is showing</h3>}
        {searchbarToggle && <h3>Searchbar is showing</h3>}

      </div>
    </React.Fragment>
  )
}
export default Header

А это мой HeaderContext.jsx

import React, { createContext, useState } from "react";
import PropTypes from "prop-types";

export const Context = createContext({});

export const Provider = props => {
  const {
    navbarToggle: initialNavBarToggle,
    searchbarToggle: initialSarchbarToggle,
    children
  } = props;

  const [navbarToggle, setNavbarToggle] = useState(initialNavBarToggle);
  const [searchbarToggle, setSearchbarToggle] = useState(initialSarchbarToggle);

  const headerContext = {
    navbarToggle, setNavbarToggle,
    searchbarToggle, setSearchbarToggle
  };

  return <Context.Provider value={headerContext}>{children}</Context.Provider>;
};

export const { Consumer } = Context;

Provider.propTypes = {
  navbarToggle: PropTypes.bool,
  searchbarToggle: PropTypes.bool
};

Provider.defaultProps = {
  navbarToggle: false,
  searchbarToggle: false
};

Надеюсь, вы сможете пролить немного света на это для меня

- правка -

Это мой код, основанный на принятом ответе.

import React, { useContext } from "react"
import { Provider,Context } from "./HeaderContext"

export const HeaderWithContext= () => {

  const headerContext = useContext(Context)
  const { navbarToggle, setNavbarToggle, searchbarToggle, setSearchbarToggle } = headerContext

  return (
    <React.Fragment>
      <div className={"sticky-top"}>

        <button onClick={ () => setNavbarToggle( !navbarToggle )}> Toggle Menu </button>
        <button onClick={ () => setSearchbarToggle( !searchbarToggle )}> Toggle Search </button>

        {navbarToggle && <h3>Menu is showing</h3>}
        {searchbarToggle && <h3>Searchbar is showing</h3>}

      </div>
    </React.Fragment>
  )
}

export const Header = () => {
  return (
    <Provider>
      <HeaderWithContext/>
    </Provider>
  )
};

1 Ответ

2 голосов
/ 01 мая 2020

Один из родительских компонентов, например, App, должен обернуть заголовок (или один из его компонентов-предков) с помощью Context.Provider :

import { Provider } from "./HeaderContext"
...
<Provider>
  <Header />
</Provider>  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...