Hi there,
I did the new react course and tried to do my own project. But now I have problem! I developed a simple user login. I have a asp dotnet backend where I get as a response a user id and a token. I implemented a authStore with zustand. I can do "console.log(user) and get all my data in console. But if I do it in the return statement, I get an empty object. I don’t get what I did wrong. Maybe somebody has an idea?
my user form:
const validationSchema = yup.object({
username: yup.string().required("username required"),
password: yup.string().required("Password is required"),
});
const Login = () => {
const navigate = useNavigate();
const [loading, setLoading] = useState<boolean>(false);
const logUser = useLogin(() => {});
const formik = useFormik({
initialValues: {
username: "",
password: "",
},
validationSchema: validationSchema,
onSubmit: (values: { username: string; password: string }) => {
alert(JSON.stringify(values, null, 2));
setLoading(true);
logUser.mutate({
id: "",
username: values.username,
password: values.password,
token: "",
});
navigate("/profile");
},
});
return (
<Box>
<form onSubmit={formik.handleSubmit}>
<Box
display="flex"
flexDirection={"column"}
maxWidth={600}
alignItems={"center"}
justifyContent={"center"}
margin="auto"
marginTop={25}
padding={3}
borderRadius={5}
boxShadow={"5px 5px 10px #000"}
sx={{
":hover": {
boxShadow: "10px 10px 20px #000",
},
}}
>
<img src={logo} width={150} height={150} />
<Typography variant="h2" padding={3} textAlign={"center"}>
Login
</Typography>
<TextField
id="username"
name="username"
margin="normal"
value={formik.values.username}
type={"text"}
variant="outlined"
placeholder="Username"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.username && Boolean(formik.errors.username)}
helperText={formik.touched.username && formik.errors.username}
/>
<TextField
id="password"
name="password"
value={formik.values.password}
margin="normal"
type={"password"}
variant="outlined"
placeholder="Password"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.password && Boolean(formik.errors.password)}
helperText={formik.touched.password && formik.errors.password}
/>
<Button
type="submit"
sx={{ marginTop: 3, borderRadius: 3 }}
variant="contained"
color="primary"
disabled={loading}
>
{loading && (
<span className="spinner-border spinner-border-sm"></span>
)}
Login
</Button>
</Box>
</form>
</Box>
);
};
export default Login;
my profile component where I want to display user information:
const Profile = () => {
const { user } = useAuthStore();
console.log("Profile", user);
return (
<div>
<h3>{user.token}</h3>
<h3>{user.id}</h3>
<h3>{user.username}</h3>
</div>
);
};
export default Profile;
my useLogin hook:
const useLogin = (onLogIn: () => void) => {
const { login } = useAuthStore();
const queryClient = useQueryClient();
return useMutation<IUser, Error, IUser>({
mutationFn: authService.login,
onSuccess: (newUser) => {
queryClient.setQueryData<IUser>(["users"], newUser);
login(newUser);
console.log("Logged in successful!", newUser);
},
onError: (error) => {
console.log(error.message);
},
});
};
export default useLogin;
my apiClient:
const axiosInstance = axios.create({
baseURL: "some url"
});
class APIClient<T> {
endpoint: string;
constructor(endpoint: string) {
this.endpoint = endpoint;
}
getAll = () => {
return axiosInstance.get<T[]>(this.endpoint).then((res) => res.data);
};
getString = () => {
return axiosInstance.get(this.endpoint).then((res) => res.data);
};
get = () => {
return axiosInstance.get<T>(this.endpoint).then((res) => res.data);
};
login = (data: IUser) => {
return axiosInstance.post<IUser>(this.endpoint, data).then((response) => {
return response.data;
});
};
post = (data: T) => {
return axiosInstance.post<T>(this.endpoint, data).then((res) => res.data);
};
}
export default APIClient;
my authStore:
export interface IUser {
id?: string;
username?: string;
password?: string;
token?: string;
}
interface AuthStore {
user: IUser;
login: (user: IUser) => void;
}
const useAuthStore = create<AuthStore>((set) => ({
user: {},
login: (user) => set(() => ({ user: user })),
}));
export default useAuthStore;