我有一个反应组件,它根据用户的登录状态有条件地渲染JSX。
<div>
{ boolIsLoggedIn ?
<SomeLoggedInComponent /> : <SomeNotLoggedInComponent /> }
</div>
我想我需要使用React.useState()
和/或React.useEffect()
但我不确定如何实现它。
我试过这个:
const [boolIsLoggedIn, setBoolIsLoggedIn] = useState(isLoggedIn())
useEffect(() => {
const checkLogIn = () => {
setBoolIsLoggedIn(isLoggedIn())
}
checkLogIn()
})
其中 isLoggedIn() 检查用户是否已登录并返回布尔值。
目前,我可以注销并登录并且isLoggedIn()
功能有效,但是我想有条件地重新渲染的组件在刷新页面之前不会这样做。
所以我[isLoggedin()]
作为第二个参数添加到useEffect()
,现在它几乎可以工作了。当我登录时,boolIsLoggedIn
值变为 true,组件重新渲染。但是,当我重新注销时boolIsLoggedIn
在刷新页面之前不会更改。 这是我的isLoggedIn()函数的代码,该函数在单独的文件中编码并导入:
let boolIsLoggedIn = false
export const setUser = user => {
//handle login
boolIsLoggedIn = true
export const logout => {
//handle logout
boolIsLoggedIn = false
}
export const isLoggedIn = () =>
return boolIsLoggedIn
}
试试这个
import React, { Component } from "react";
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: isLoggedIn()
};
}
render() {
let { isLoggedIn } = this.state;
return (
<div className="App">
{(function() {
if (isLoggedIn) {
return <div>Login</div>;
} else {
return <div>with out Login</div>;
}
})()}
</div>
);
}
}
export default App;
- 您缺少定义状态的开放 [。
- 我会将 defailt 值设置为 false,这样您就不会执行该函数两次。 使用效果通常需要一个依赖数组作为第二个参数
- ,但由于您只想运行它一次(在组件挂载后),只需放置一个空数组作为第二个参数。
- 另一件事是,如果
isLoggedIn
函数是异步的,则必须通过使用 await 并将父函数设置为异步来等待它。如果函数是异步的,这肯定是您遇到的问题。
更改以下内容:
const boolIsLoggedIn, setBoolIsLoggedIn] = useState(isLoggedIn())
useEffect(() => {
const checkLogIn = () => {
setBoolIsLoggedIn(isLoggedIn())
}
checkLogIn()
})
对此:
const [boolIsLoggedIn, setBoolIsLoggedIn] = useState(isLoggedIn());
useEffect(() => {
(() => {
setBoolIsLoggedIn(isLoggedIn());
})();
}, [isLoggedIn()]);
祝你好运
你需要能够共享反应状态,而不仅仅是值,以便触发反应重新渲染。在您的示例中,您需要调用setBoolIsLoggedIn()
每当isLoggedIn()
的值发生变化时,才能更改状态并触发组件的重新呈现。
组件之间共享状态的另一种方式是通过 React Context。首先需要创建一个上下文提供程序,如下所示:
const UserContext = React.createContext();
export function UserProvider({ children }) {
const [ user, setUser ] = useState({ loggedIn: false });
return (
<UserContext.Provider value={[ user, setUser ]}>
{ children }
</UserContext.Provider>
)
}
在这种情况下,UserProvider
是维护与user={ loggedIn }
共享状态的那个。然后,您需要使用此提供程序包装 React App 组件,以便组件能够共享状态。
要设置共享user
状态,您可以使用挂钩useContext(UserContext)
并通过挂钩提供setUser
更改状态。在下面的示例中,我们有一个设置共享user
状态的登录按钮组件:
function LoginButton() {
const [user, setUser] = useContext(UserContext);
/** flip login state when button is clicked */
function logIn() {
setUser(state => ({ ...state, loggedIn: !state.loggedIn }) );
}
return (
<button onClick={logIn}>{ user.loggedIn ? "Log Out" : "Log In"}</button>
);
}
最后,为了能够使用共享user
状态并在用户状态更改时触发重新渲染,您将再次使用不同组件中的钩子useContext(UserContext)
来获得如下状态:
export default function App() {
const [user,] = useContext(UserContext);
return (
<div className="App">
<h1>Conditional React component</h1>
<h2>Click on the button to login/logout</h2>
<LoginButton></LoginButton>
<div>
{ user.loggedIn ? <LoggedInComponent/> : <LoggedOutComponent/>}
</div>
</div>
);
}
我在这里提供了一个示例来展示这一切是如何协同工作的。