reactjs - 用户授权后如何在所有子组件之间传递状态?

标签 reactjs react-context

服务器正在返回用户数据。我尤其对他的权利感兴趣。有了这些权利,我将渲染组件。我正在考虑将这些数据传递给组件并进行一些检查。所有路由都在 index.js 中

import {Notfound404} from './components/404/404NotFound'
import {UserContext} from './UserContext'

const Router = () => {

    const [user, setUser] = useState(null)

    return (
        <React.StrictMode>
            <UserContext.Provider value={{user, setUser}}>
                <CookiesProvider>
                    <BrowserRouter>
                        <Switch>
                            <Route exact path={'/'} component={Auth}/>
                            <Route exact path={'/settings'} component={Settings}/>
                            <Route exact path={'/event-logs'} component={EventLog}/>
                            <Route component={Notfound404} status={404}/>
                        </Switch>
                    </BrowserRouter>
                </CookiesProvider>
            </UserContext.Provider>
        </React.StrictMode>
    )
}

在 Auth.js 中设置用户数据

import {UserContext} from '../../UserContext'

export const Auth = () => {

    const {user, setUser} = useContext(UserContext)

    const [username, setUsername] = useState('')
    const [password, setPassword] = useState('')
    const [token, setToken] = useCookies(['qr-token'])

    useEffect(() => {
        if (token['qr-token']) window.location.href = '/settings'
    }, [token])

    const credentials = {
        username: username,
        password: password
    }

    const sendCredentials = () => {
        axios.post(`http://127.0.0.1:8000/api/v1/auth/`, credentials, {
            headers: {
                'Content-type': 'application/json',
            }
        })
            .then(resp => {
                setToken('qr-token', resp.data.token);
                setUser(resp.data)
            })
            .catch(error => console.log(error.response))
    }

    return !token['qr-token'] &&
        <div className={styles.authContainer}>
            <label htmlFor={'username'}>Username</label>
            <input id={'username'} type={'text'} placeholder={'username'}
                   onChange={evt => setUsername(evt.target.value)}
            />
            <label htmlFor={'password'}>Password</label>
            <input id={'password'} type={'password'} onChange={evt => 
                setPassword(evt.target.value)}/>
            <button onClick={sendCredentials}>Sign In</button>
        </div>
    )
}

在 index.js 中,我在授权后获取用户数据。但是在settings.js中使用数据为空

export const Settings = () => {

    const {user, setUser} = useContext(UserContext)
    console.log(user) # null
....
}

可能我做错了什么,我正在寻求你的帮助。谢谢。

最佳答案

正如 Saba 所指出的,问题在于刷新页面以清除上下文。这是通过以下行完成的:

useEffect(() => {
    if (token['qr-token']) window.location.href = '/settings'
}, [token])

不要在单页应用程序中使用通常的重定向方法。相反,使用

const history = useHistory();
useEffect(() => {
    if (token['qr-token'])
        history.push('/settings');
}, [token])

这不会导致页面重新加载,因此可以使您的上下文保持事件状态。

关于reactjs - 用户授权后如何在所有子组件之间传递状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64511255/

相关文章:

javascript - React - 如何从另一个函数内部调用一个函数

javascript - 如何使用快照在 useEffect 内使用异步回调来测试功能组件

reactjs - React Context API - 在页面刷新时保留数据

reactjs - typescript react 上下文+类型 '{}'没有调用签名

javascript - 在 AJAX 请求后,如何使用 react 上下文 api 值更新 Formik 初始值?

reactjs - 解析错误 : Argument for '--jsx' option must be: 'preserve' , 'react-native' , 'react'

javascript - 如何将 react 组件呈现给另一个网络应用程序

javascript - 如何在 React.js 中渲染页面之前等待 fetch 完成

javascript - Gatsby 中 Context Provider 放在哪里?

reactjs - react : Difference between a Stateful Class Component and a Function Component using Hooks?