Javascript 反应:无法使用useContext钩子在app.js中设置上下文状态
我无法在app.js中设置上下文状态,不知何故,我在其中获得了空值,但可以在子组件中访问它 每当用户来到页面时,我想在app.js中设置上下文状态,以便我可以在整个应用程序中使用它,例如,根据用户是否登录显示不同的标题 请求的沙箱URL-> 我在跟踪 app.jsJavascript 反应:无法使用useContext钩子在app.js中设置上下文状态,javascript,reactjs,react-hooks,react-context,Javascript,Reactjs,React Hooks,React Context,我无法在app.js中设置上下文状态,不知何故,我在其中获得了空值,但可以在子组件中访问它 每当用户来到页面时,我想在app.js中设置上下文状态,以便我可以在整个应用程序中使用它,例如,根据用户是否登录显示不同的标题 请求的沙箱URL-> 我在跟踪 app.js // import installed dependencies import React, { useEffect, useContext } from 'react'; import { BrowserRouter as Rout
// import installed dependencies
import React, { useEffect, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
// import custom contexts
import { AuthContext, AuthContextProvider } from './contexts/auth/AuthContext';
// import pages
import Homepage from './pages/homepage/Homepage';
// import components
import Footer from './components/footer/Footer';
import Header from './components/header/Header';
export default function App() {
const [authState, setAuthState] = useContext(AuthContext);
useEffect(() => {
console.log(authState); // prints *{}*
console.log(setAuthState); // prints *() => {}*
const token = localStorage.getItem('token');
const tokenIsExpired = parseInt(localStorage.getItem('tokenIsExpired'));
if (!tokenIsExpired && token.length) {
setAuthState({
userIsLoggedin: true,
fName: 'test fname',
lName: 'test lname',
userName: 'testname'
});
} else {
setAuthState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
}
if (tokenIsExpired) {
localStorage.setItem('token', '');
}
}, [authState, setAuthState]);
return (
<Router>
<AuthContextProvider value={[authState, setAuthState]}>
<div className='App'>
<Header />
<Switch>
<Route exact path='/'>
<Homepage />
</Route>
</Switch>
<Footer />
</div>
</AuthContextProvider>
</Router>
);
}
import React, { useState, createContext } from 'react';
const AuthContext = createContext([{}, () => {}]);
const AuthContextProvider = (props) => {
const [authState, setAuthState] = useState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
return (
<AuthContext.Provider value={[authState, setAuthState]}>
{props.children}
</AuthContext.Provider>
);
};
export { AuthContext, AuthContextProvider };
import { useContext } from 'react';
import { AuthContext } from './AuthContext';
const useAuthContext = () => {
const [authState, setAuthState] = useContext(AuthContext);
const login = (loginDetails) => {
setAuthState({
userIsLoggedin: true,
fName: 'test fname',
lName: 'test lname',
userName: 'testname'
});
};
const logout = () => {
setAuthState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
};
return { login, logout };
};
export default useAuthContext;
// import installed dependencies
import React, { useContext, useEffect } from 'react';
// import components
import LoggedOutHeader from './logged-out-header/LoggedOutHeader';
import LoggedInHeader from './logged-in-header/LoggedInHeader';
// import custom contexts
import { AuthContext } from '../../contexts/auth/AuthContext';
const Header = () => {
const [authState, setAuthState] = useContext(AuthContext);
console.log(authState); //prints *{userIsLoggedin: false, fName: "", lName: "", userName: ""}*
console.log(setAuthState); //prints *ƒ dispatchAction(fiber, queue, action) {...*
const header = authState.isUserLoggedIn ? (
<LoggedInHeader />
) : (
<LoggedOutHeader />
);
return header;
};
export default Header;
Header.js
// import installed dependencies
import React, { useEffect, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
// import custom contexts
import { AuthContext, AuthContextProvider } from './contexts/auth/AuthContext';
// import pages
import Homepage from './pages/homepage/Homepage';
// import components
import Footer from './components/footer/Footer';
import Header from './components/header/Header';
export default function App() {
const [authState, setAuthState] = useContext(AuthContext);
useEffect(() => {
console.log(authState); // prints *{}*
console.log(setAuthState); // prints *() => {}*
const token = localStorage.getItem('token');
const tokenIsExpired = parseInt(localStorage.getItem('tokenIsExpired'));
if (!tokenIsExpired && token.length) {
setAuthState({
userIsLoggedin: true,
fName: 'test fname',
lName: 'test lname',
userName: 'testname'
});
} else {
setAuthState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
}
if (tokenIsExpired) {
localStorage.setItem('token', '');
}
}, [authState, setAuthState]);
return (
<Router>
<AuthContextProvider value={[authState, setAuthState]}>
<div className='App'>
<Header />
<Switch>
<Route exact path='/'>
<Homepage />
</Route>
</Switch>
<Footer />
</div>
</AuthContextProvider>
</Router>
);
}
import React, { useState, createContext } from 'react';
const AuthContext = createContext([{}, () => {}]);
const AuthContextProvider = (props) => {
const [authState, setAuthState] = useState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
return (
<AuthContext.Provider value={[authState, setAuthState]}>
{props.children}
</AuthContext.Provider>
);
};
export { AuthContext, AuthContextProvider };
import { useContext } from 'react';
import { AuthContext } from './AuthContext';
const useAuthContext = () => {
const [authState, setAuthState] = useContext(AuthContext);
const login = (loginDetails) => {
setAuthState({
userIsLoggedin: true,
fName: 'test fname',
lName: 'test lname',
userName: 'testname'
});
};
const logout = () => {
setAuthState({
userIsLoggedin: false,
fName: '',
lName: '',
userName: ''
});
};
return { login, logout };
};
export default useAuthContext;
// import installed dependencies
import React, { useContext, useEffect } from 'react';
// import components
import LoggedOutHeader from './logged-out-header/LoggedOutHeader';
import LoggedInHeader from './logged-in-header/LoggedInHeader';
// import custom contexts
import { AuthContext } from '../../contexts/auth/AuthContext';
const Header = () => {
const [authState, setAuthState] = useContext(AuthContext);
console.log(authState); //prints *{userIsLoggedin: false, fName: "", lName: "", userName: ""}*
console.log(setAuthState); //prints *ƒ dispatchAction(fiber, queue, action) {...*
const header = authState.isUserLoggedIn ? (
<LoggedInHeader />
) : (
<LoggedOutHeader />
);
return header;
};
export default Header;
//导入已安装的依赖项
从“React”导入React,{useContext,useEffect};
//导入组件
从“./LoggedOutHeader/LoggedOutHeader”导入LoggedOutHeader;
从“./LoggedInHeader/LoggedInHeader”导入LoggedInHeader;
//导入自定义上下文
从“../../contents/auth/AuthContext”导入{AuthContext};
常量头=()=>{
const[authState,setAuthState]=useContext(AuthContext);
console.log(authState);//打印*{userIsLoggedin:false,fName:,lName:,userName:}*
log(setAuthState);//打印*调度操作(光纤、队列、操作){*
const header=authState.isUserLoggedIn(
) : (
);
返回头;
};
导出默认标题;
您正在将值
传递给AuthContextProvider
,它似乎是您想要使用的值,而您没有使用它
// value not used inside `AuthContextProvider`
<AuthContextProvider value={[authState, setAuthState]}>
//值未在`AuthContextProvider'中使用`
应该是:
const AuthContextProvider = (props) => {
return (
<AuthContext.Provider value={props.value}>
{props.children}
</AuthContext.Provider>
);
};
const AuthContextProvider=(道具)=>{
返回(
{props.children}
);
};
您正在应用组件中使用未包装在AuthContextProvider中的上下文。在这种情况下,应用组件中的useContext调用将不会返回提供给AuthContextProvider的值,而是返回提供给createContext调用的“默认”值
您需要将应用程序组件中的逻辑延迟到AuthContextProvider中的子组件
见以下注释:
defaultValue参数仅在组件树中其上方没有匹配的提供程序时使用。这有助于在不包装组件的情况下单独测试组件。注意:将未定义的作为提供程序值传递不会导致使用组件使用defaultValue。您可以使用上下文提供程序内部index.js
ReactDOM.render(
<AuthContextProvider>
<App />
</AuthContextProvider>,
document.getElementById('root')
)
ReactDOM.render(
,
document.getElementById('root'))
)
Rule 101切勿在UseEffect的依赖项数组中添加setter函数。请创建一个沙盒,并在app.js中共享仍然获得相同的空值。是否有可生产的示例?是否添加了有疑问的沙盒