Я использую React, Graphql и Apollo.
Мой индекс. 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 ( ... )
В де <App />
я выполняю запрос Graphql к бэкэнду получить данные текущего пользователя. Этот застрявший код в бэкэнде работает должным образом.
<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
}
})
};
Но проблема в том, что когда я вхожу в систему с одним пользователем и выходом из системы, а затем вхожу с другим пользователем, я все еще вижу старого. Если я затем перефразирую sh, я вижу нового пользователя.
Есть идеи, что я делаю неправильно?
ОБНОВЛЕНИЕ
Компонент <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>
)