React useState() & useContext() - TypeError: setState is not a function - What am I doing wrong?
React useState() & useContext() - TypeError: setState is not a function - What am I doing wrong?
我有几个 React 功能组件,我想共享一个状态。在此示例中,有条件地 show/hide 搜索栏和导航栏的两个切换按钮。
--解决方案,基于接受的答案,在底部--
我是 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>
)
};
parent 个组件之一,例如应用程序必须用 Context.Provider:
包装 header(或其祖先组件之一)
import { Provider } from "./HeaderContext"
...
<Provider>
<Header />
</Provider>
我有几个 React 功能组件,我想共享一个状态。在此示例中,有条件地 show/hide 搜索栏和导航栏的两个切换按钮。
--解决方案,基于接受的答案,在底部--
我是 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>
)
};
parent 个组件之一,例如应用程序必须用 Context.Provider:
包装 header(或其祖先组件之一)import { Provider } from "./HeaderContext"
...
<Provider>
<Header />
</Provider>