因此,我遵循这个tutorial,通过react context api使用全局状态。
我想根据用户是否登录来更改导航栏,我需要使用全局状态。但是我看到白色,所以我认为我做错了什么。
应用程序上下文.js
import React from "react";
// ./components/AppContext.js
const AppContext = React.createContext();
export default AppContext;
索引.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import reportWebVitals from './reportWebVitals';
import { CookiesProvider } from 'react-cookie';
import App from "./App";
import AppContext from "./components/AppContext";
// index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<CookiesProvider>
<App/>
</CookiesProvider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals();
应用程序js
import React, {useState} from 'react';
import './App.css';
import Home from './Home';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import User from "./User";
import NavBarSI from "./components/NavBarSignedIn";
import NavBarGL from "./components/NavBarGeneral";
import AppContext from "./components/AppContext";
//App.js
const App = () => {
const userSettings = {
setting2name: setting2value,
setSetting2value
};
const [setting2value, setSetting2value] = useState(false);
const navbar = setting2value ?
<NavBarSI/> : <NavBarGL/>
return (
<Router>
<AppContext.Provider value={userSettings}>
{navbar}
<NavBarSI/>
<div>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/user" element={<User/>}/>
</Routes>
</div>
</AppContext.Provider>
</Router>
);
}
export default App;
Home.js示例中,当用户登录时,我将布尔值更改为true。
import React, {useContext, useEffect, useState} from 'react';
import './App.css';
import { Button, Container } from 'reactstrap';
import { useCookies } from 'react-cookie';
import AppContext from "./components/AppContext";
// Home.js
const Home = () => {
const myContext = useContext(AppContext);
const [authenticated, setAuthenticated] = useState("authenticated");
const [loading, setLoading] = useState(false);
const [user, setUser] = useState(undefined);
const [cookies] = useCookies(['XSRF-TOKEN']);
useEffect(() => {
setLoading(true);
fetch('/user', { credentials: 'include' })
.then(response => response.text())
.then(body => {
if (body === '') {
setAuthenticated(false);
} else {
setUser(JSON.parse(body));
setAuthenticated(true);
myContext.setSetting2value(true);
}
setLoading(false);
});
}, [setAuthenticated, setLoading, setUser])
const login = () => {
let port = (window.location.port ? ':' + window.location.port : '');
if (port === ':3000') {
port = ':8080';
}
window.location.href = `//${window.location.hostname}${port}/private`;
}
const logout = () => {
fetch('/user/logout', {
method: 'POST', credentials: 'include',
headers: { 'X-XSRF-TOKEN': cookies['XSRF-TOKEN'] }
})
.then(res => res.json())
.then(response => {
window.location.href = `${response.logoutUrl}&returnTo=${window.location.origin}`;
});
}
const message = user ?
<h2>Welcome, {user.name}!</h2> :
<p>Please log in to manage your JUG Tour.</p>;
const button = authenticated ?
<div>
<br/>
<Button color="link" onClick={logout}>Logout</Button>
</div> :
<Button color="primary" onClick={login}>Login</Button>;
if (loading) {
return <p>Loading...</p>;
}
return (
<div>
<Container fluid>
{message}
{button}
</Container>
</div>
);
}
export default Home;
1条答案
按热度按时间brtdzjyr1#
您得到白屏是因为试图在变量声明之前对其赋值。
交换变量应该可以了
此外,我建议记住你的上下文对象,以防止额外的重新渲染使用
useMemo
。就像这样:
希望能有所帮助!