首页 > 解决方案 > React Context : 等待上下文值加载 Header

问题描述

早上好,在这里我尝试使用从我的连接 api 接收到的身份验证和用户数据的上下文,我完美地接收到我的数据并且连接正常工作,直到一切顺利。但我想将我的上下文移动到我的标题中以在标题中显示它。但是我有一个问题,登录后,我需要重新加载页面一次,然后才能将用户名放在标题上,我得出的结论是标题在上下文更新值之前加载。而且我真的不明白如何在显示标题之前等待加载上下文变量

这是我的上下文:

import React from 'react';

export default React.createContext({
    isAuthenticated: false,
    setIsAuthenticated: (value) => {},
    userData: {}
})

这是我的 app.js :

const App  = () => {

    const [isAuthenticated, setIsAuthenticated] = useState(
        AuthAPI.isAuthenticated()
    );

    const[userData, setUserData] = useState(
        authAPI.getUserData()
    )

    const HeaderWithRouter = withRouter(Header);

    return (
        <AuthContext.Provider value={{isAuthenticated, setIsAuthenticated,userData}}>
            <HashRouter>
                <HeaderWithRouter />
                <div className="container">
                    <Switch>
                        <Route exact path="/" component={Home}/>
                        <Route exact path="/login" component={Login}/>
                        <Route exact path="/profil/:id" component={Profil}/>
                        <Route exact path="/register" component={Register}/>       
                    </Switch>
                </div>
                <Footer/>
            </HashRouter>
            <ToastContainer position={toast.POSITION.BOTTOM_RIGHT} />
        </AuthContext.Provider>
    )
}

ReactDOM.render(<App/>, document.getElementById('app'));

这是我的标题:

const Header = ({history}) => {

    const {isAuthenticated, setIsAuthenticated,userData} = useContext(AuthContext)
    const [isToggled, setToggled] = useState(false);

    const handleLogout = () => {
        authAPI.logout()
        setIsAuthenticated(false)
        toast.success('Vous êtes déconnecté !')
        history.push('/')
    }

    const toggleTrueFalse = () => setToggled(!isToggled);

    return( 
        <nav className="headerNav">
            <Link to="/"><img src={Logo} className="VSLogo"/></Link>
            <ul>
                <li className="navItem"><Link to="/teams">Teams</Link></li>
                <li className="navItem"><Link to="/tournaments">Tournaments</Link></li>
                <li className="navItem"><Link to="/esport">Esport</Link></li>
            </ul>
            {(!isAuthenticated && (
                <>
                    <Link to="/register" className="signUpBtn">Sign up</Link>
                    <Link to="/login" className="connexionBtn">Sign in</Link>
                </>
            )) || (
                <>
                    <span onClick={toggleTrueFalse}>{userData.pseudo}</span>
                    <div className={`userPopup ${isToggled ? "show" : ""}`} style={{}}>
                        <ul>
                            <li><span className="font-heavy red"><Link to={'/profil/' + userData.id}>{userData.pseudo}</Link></span></li>
                            <li>Paramètres</li>
                            <li onClick={handleLogout}>Deconnect</li>
                        </ul>
                    </div>  
                </>
            )}
        </nav>
    )
}

export default Header;

这是我的登录组件的一部分,用于设置 IsAuthenticated :

const { setIsAuthenticated } = useContext(AuthContext);

    const [credentials, setCredentials] = useState({
      username: "",
      password: ""
    });

    const [error, setError] = useState("");

      //Gestion du submit
    const handleSubmit = async event => {
        event.preventDefault();
        try {
            await AuthAPI.authenticate(credentials);
            setError("");
            setIsAuthenticated(true);
            history.replace("/");
        } catch (error) {
            setError("Error");
        }
    };

在标题的末尾, userData.pseudo 应该显示用户名,但如果我不重新加载,什么都没有。

谢谢 !

标签: javascriptreactjsreact-hooks

解决方案


尝试添加一个useEffect如果isAuthenticated更改将同步用户数据:

useEffect(() => {
    if (isAuthenticated) {
        setUserData(AuthAPI.getUserData())
    }
}, [isAuthenticated])

推荐阅读