我目前正在学习使用上下文API进行react ,基本上我try 在上下文中使用State来判断用户是否使用简单的Boolean isAuthated State登录.问题是,尽管上下文对两个组件都可见,但对所述状态所做的任何更改都不会像使用上下文时那样反映到其他组件中.
这是我的代码,
AuthContext.js
import React, { createContext, useState } from 'react';
export const AuthContext = createContext();
export const AuthContextProvider = ({ children }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
console.log("AuthCOntext", AuthContext);
const contextValue = {
isAuthenticated,
// updateIsAuthenticated,
setIsAuthenticated
};
return (
<AuthContext.Provider value={contextValue}>
{children}
</AuthContext.Provider>
);
};
LoginForm.js
import React, { useContext, useEffect, useState } from 'react';
import Button from 'react-bootstrap/Button';
import formStyles from '../../styles/form.module.css';
import { postLoginForm } from '../../helpers/RequestHelper';
import { AuthContext } from '../../contexts/AuthContext';
export default function LoginForm() {
const { isAuthenticated, setIsAuthenticated } = useContext(AuthContext);
const [returnedResponseState, setReturnedResponseState] = useState({
status: 0,
text: ''
})
async function submitLoginForm(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const actualFormData = Object.fromEntries(formData.entries());
console.log(actualFormData);
console.log("Before updateIsAuthenticated:", isAuthenticated);
await postLoginForm(actualFormData).then(
(res) => {
console.log(res);
if (!res) {
}
else {
setReturnedResponseState({ status: res.status, text: res.data }, () => {
console.log(returnedResponseState);
});
if (res.status === 200) {
setIsAuthenticated(true);
}
}
});
console.log("after updateIsAuthenticated", isAuthenticated);
}
return (
<div className={formStyles.formDiv} id='loginform'>
{console.log(isAuthenticated)}
<form onSubmit={submitLoginForm}>
<h5>Login</h5>
<div>
{returnedResponseState ? returnedResponseState.text : null}
</div>
<div className={formStyles.formElement}>
<label htmlFor="emailID" className={formStyles.formElementLabel}>Email ID</label>
<input type='email' name="emailID" placeholder="something@example.com"></input>
</div>
<div className={formStyles.formElement}>
<label htmlFor="Password1" className={formStyles.formElementLabel}>Password</label>
<input type="password" name="password1" placeholder="*****"></input>
</div>
<Button type='submit'> Log in</Button>
</form>
</div>
)
}
Library.js
import React, { useState, useEffect, useContext } from 'react';
import Card from 'react-bootstrap/Card';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import { AuthContext } from '../../contexts/AuthContext';
import { getUserData } from '../../helpers/RequestHelper';
export default function Library() {
const { isAuthenticated } = useContext(AuthContext);
const [response, setResponse] = useState(null);
useEffect(() => {
async function getUserPageData() {
const result = await getUserData();
setResponse(result.playlist);
console.log("Is authenticated", isAuthenticated);
}
getUserPageData();
}, []); // Add isAuthenticated as a dependency
return (
<div>
<div>
<h5>Your Playlists</h5>
<h6>playlist name</h6>
<Row xs={1} md={2} lg={3} xl={3}>
{response && response.length !== 0 ? (
response.map((video) => (
<Col>
<Card>
<p>{video.title}</p>
</Card>
</Col>
))
) : (
<p>You currently have no playlists created</p>
)}
</Row>
</div>
</div>
);
}
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { AuthContextProvider } from './contexts/AuthContext';
import { Children } from 'react';
const root = ReactDOM.createRoot(document.getElementById('root'));
console.log(root);
root.render(
<React.StrictMode>
<AuthContextProvider value={Children}>
<App />
</AuthContextProvider>
</React.StrictMode>
);
reportWebVitals();
App.js
import './App.css';
import {
createBrowserRouter,
Outlet,
RouterProvider,
} from 'react-router-dom';
import Index from './components/Index';
import NavigationBar from './components/Navbar/NavigationBar';
import VideoPlayerPage from './views/VideoPlayerPage'
import AccountPage from './views/AccountPage';
import LoginSignupPage from './views/LoginSignupPage';
import Library from './components/Account/Library';
import UploadVideoForm from './components/Forms/UploadVideoForm';
const router = createBrowserRouter([
{
path: "/",
element: <Index />
},
{
path: "/watch/:videoId",
element: <VideoPlayerPage />
},
{
path: "/login",
element: <LoginSignupPage />
},
{
path: "/user/home",
element: <AccountPage />
},
{
path: "/library",
element: <Library />
},
{
path: "/upload",
element: <UploadVideoForm />
}
])
function App() {
return (
<>
<NavigationBar />
<RouterProvider router={router}>
<Outlet />
</RouterProvider>
</>
);
}
export default App;
我在这里可能错了,但我已经try 包装上下文函数是useEffect钩子来触发可能正在使用AuthContext的任何组件的重新呈现,到目前为止我无法找到答案,因为在我看来一切都是正确的,并且react 和开发人员控制台都没有引发任何错误,除非出现警告:来自useState()和useReducer()钩子的状态更新不支持第二个回调参数.要在呈现后执行副作用,请使用useEffect()在组件主体中声明它.