【发布时间】:2020-08-18 15:43:57
【问题描述】:
我正在使用 React、Graphql 和 Apollo。
我的 index.js 如下:
const client = new ApolloClient({
uri: GRAPHQL_URL,
fetchOptions: {
credentials: 'include'
},
request: (operation) => {
const token = localStorage.getItem(AUTH_TOKEN_KEY) || "";
operation.setContext({
headers: {
Authorization: `JWT ${token}`
}
})
},
clientState: {
defaults: {
isLoggedIn: !!localStorage.getItem(AUTH_TOKEN_KEY)
}
}
});
const IS_LOGGED_IN_QUERY = gql`
query {
isLoggedIn @client
}
`;
ReactDOM.render(
<ApolloProvider client={client}>
<Query query={IS_LOGGED_IN_QUERY}>
{({data}) => {
return data.isLoggedIn ? <App/> : <Login/>
}}
</Query>
</ApolloProvider>,
document.getElementById('root')
);
因此,如果用户已登录,我将令牌保存到 localStorage 并显示 <App /> 而不是 <Login />
<Login />如下:
const Login = () => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [logIn, { loading: mutationLoading, error: mutationError }] = useMutation(LOG_IN_MUTATION);
const client = useApolloClient();
const handleSubmit = async (e) => {
e.preventDefault();
const res = await logIn({variables: {username, password}});
client.writeData({ data: { isLoggedIn: true } })
localStorage.setItem(AUTH_TOKEN_KEY, res.data.tokenAuth.token);
};
return ( ... )
在 de <App /> 中,我对后端进行 Graphql 查询以获取当前登录用户的 de 数据。后端卡住的代码按预期工作。
<App />如下:
function App() {
const {loading, error, data} = useQuery(GET_ME);
if (loading) return <div><LoadingIndicator1/></div>
if (!loading && error) return <div ><ErrorIndicator/></div>
return (
...
);
}
export default App;
而GET_ME查询如下:
export const GET_ME = gql`
{
me{
id
username
firstName
lastName
email
}
}
`;
退出功能如下:
const client = useApolloClient();
const signOut = (client) => {
localStorage.removeItem(AUTH_TOKEN_KEY);
client.writeData({
data: {
isLoggedIn: false
}
})
};
但问题是当我用一个用户登录并注销,然后用另一个用户登录时,我仍然看到旧用户。如果我随后刷新,我会看到新用户。
知道我做错了什么吗?
更新
<App />组件如下:
function App() {
const {loading, error, data} = useQuery(GET_ME);
if (loading) return <div><LoadingIndicator1/></div>
if (!loading && error) return <div ><ErrorIndicator/></div>
return (
<Router>
<UserContext.Provider value={data.me}>
<ToastProvider>
<Header/>
<Switch>
<Route path="/report/:id">
<NewReport/>
</Route>
<Route exact path="/report/">
<NewReport/>
</Route>
<Route path="/reports/">
<Reports/>
</Route>
<Route exact path="/">
<Home/>
</Route>
</Switch>
</ToastProvider>
</UserContext.Provider>
</Router>
);
}
我使用用户详细信息的组件如下:
render (
<div>
{localStorage.getItem(AUTH_TOKEN_KEY) !== null && <div>
<div className=''>
<span>{currentUser.username}</span>
<i className="fad fa-angle-down" />
</div>
</div>}
</div>
)
【问题讨论】:
-
您是否在显示用户信息的组件中发送 GET_ME 查询?
-
@Rayneesh 不。我在主组件(
)中执行此操作,然后通过 React Context 将其传递给所有子组件。 -
请尝试将查询发送到您显示用户信息的位置并检查是否有帮助
-
@Rajneesh 这不是我想要的。我想在一个地方做,然后作为道具传下去。
-
所以您通过上下文传递 GET_ME 查询对吗?
标签: reactjs graphql react-apollo apollo-client