我在我的项目中使用了 React。在 App.js 文件(入口点)中,它通过这样的 API 获取当前用户。
function App() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const providerValue = useMemo(() => ({user, setUser}), [user, setUser])
useEffect(() => {
// IIF b/c u can't use async on useEffect func
(async () => {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', Cookies.get("authorization"));
const response = await fetch('http://localhost:3000/api/users/current', {headers});
const content = await response.json();
console.log({"from app user": content});
setUser(content);
})();
},[]);
return (
<Switch>
<UserContext.Provider value={providerValue}>
<Route path="/" exact
component={Home}/>
<Route path="/discover"
component={Main}/>
{/* auth */}
<Route path="/auth/signup"
component={SignUp}/>
<Route path="/auth/signin"
component={SignIn}/>
</UserContext.Provider>
</Switch>
);
}
export default App;
user 和 setUser 然后作为值传递给我的提供者 b/c 我想从其他路由访问用户数据。 当我像这样通过 useContext() 从我的应用程序组件访问用户时...
export default function DiscoverNavBar(props) {
{/* useContext to get the user*/}
const {user} = useContext(UserContext)
console.log(user);
const toggleHome = () =>{
scroll.scrollToTop()
}
return <>
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark" sticky="top">
<Link className="navbar-brand" onClick={toggleHome}>
<img alt=""
src={logo}
width="30"
height="30"
className="d-inline-block align-top"/>{' '}
Focal Addis
</Link>
<Navbar.Toggle aria-controls="responsive-navbar-nav"/>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto">
<Link className="nav-link" to="/directory">Contact us</Link>
<LinkS className="nav-link"
to="auth"
spy={true}
smooth={true}
exact="true"
duration={500} style={{cursor: "pointer"}}>Get Started</LinkS>
</Nav>
{props.children}
{/* here is the problem */}
<a>{user.email}</a>
</Navbar.Collapse>
</Navbar>
</>
}
它不断抛出一个错误,说“试图访问未定义的 .email”。当我注释掉这一行时,它编译成功,甚至用数据记录用户。
我还想在呈现登录和注册页面之前检查用户是否存在。我目前正在尝试这样做,但它也无法在正确的时刻吸引用户。它假设用户不存在。这是登录页面的代码
export default function SignIn() {
const ERR_MSSG_STYLES = {
border: "none",
color: "red",
padding: "0",
width: "100%",
backgroundColor: "transparent"
}
const {user,setUser} = useContext(UserContext)
const history = useHistory()
var errRef = useRef("")
useEffect(() => {
if (user) {
console.log("already registered");
}else{
console.log("nope");
}
}, [])
return (
<div className="container-fluid">
<div className="row" style={{height: "100vh"}}>
<div className="col-md-3 px-5">
<Formik
initialValues={{
email: '',
password: '',
}}
onSubmit={
async (values) => {
const response = await fetch('http://localhost:3000/api/users/login-influencer', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: values["email"],
password: values["password"],
})
})
const content = await response.json();
if (content["success"] == false) {
errRef.current.value = content["message"]
}else{
// change the current user in context
setUser(content)
history.replace("/discover")
Cookies.set('authorization', content["token"], { expires: 7 });
}
}
}
>
{
formik => (
<div>
<h1 className="my-4 font-weight-bold-display-4">Focal Addis</h1>
<p>Welcome back, please log in to your account</p>
<input style={ERR_MSSG_STYLES} disabled ref={errRef}/>
<Form>
<TextField label="Email" name="email" type="email"/>
<TextField label="Password" name="password" type="password"/>
<button className="btn btn-danger mt-3 shadow-none" type="submit" style={{width:"100%"}}>Sign In</button>
</Form>
<div className="mt-2 text-red text-center" >
<p>Don't have an account yet?</p>
<Link to="/auth/signup" style={{color: "red"}}>Sign up here.</Link>
</div>
</div>
)
}
</Formik>
</div>
<div className="col-md-9" style={{backgroundColor: "grey"}}>
</div>
</div>
</div>
)
}
I am trying to check if any user exists and log a mssg for now but it is only printing "nope"
答案 0 :(得分:0)
您只需要事先检查,因此电子邮件只会在准备就绪时呈现。
<a>{user?.email}</a>
也许
{user?.email &&
<a>{user.email}</a>
}
编辑 1:
您可能需要将整个内容包装在检查中以查看用户是否存在。这是一个总体思路:
return (
<>
{/*Check here if the user exists or not*/}
{user ? (
<Navbar
collapseOnSelect
expand="lg"
bg="dark"
variant="dark"
sticky="top"
>
<Link className="navbar-brand" onClick={toggleHome}>
<img
alt=""
src={logo}
width="30"
height="30"
className="d-inline-block align-top"
/>{" "}
Focal Addis
</Link>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto">
<Link className="nav-link" to="/directory">
Contact us
</Link>
<LinkS
className="nav-link"
to="auth"
spy={true}
smooth={true}
exact="true"
duration={500}
style={{ cursor: "pointer" }}
>
Get Started
</LinkS>
</Nav>
{props.children}
{user?.email && <a>{user.email}</a>}
</Navbar.Collapse>
</Navbar>
) : (
<h4>User is null</h4>
)}
</>
);
答案 1 :(得分:0)
API 调用前user 的值是什么,例如第一次渲染? 值为空,无法访问 null.email。 useEffect 和 API 调用只会在此之后发生。
为用户提供默认值
const [user, setUser] = useState({});
并检查
useEffect(() => {
if (user?.email) {
console.log("already registered");
}else{
console.log("nope");
}
}, [])