英文:
Url changed but component did not render in react router v6 anyone help me
问题
你已经创建了一个受保护的路由,当用户正确输入后,将登录页面更改为仪表板页面,一切都运行正常,但在登录后URL已更改但组件没有更改,仍然停留在登录页面。如何将组件更改为仪表板页面。
以下是翻译好的内容:
我已经在这个代码中创建了一个受保护的路由
import { useSelector } from "react-redux";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { RootState } from "src/store";
const ProtectedRoute = () => {
const location = useLocation();
// const isToken = localStorage.getItem("token") !== "";
const { isAuthenticated, loading } = useSelector(
(state: RootState) => state.login
);
if (loading) return null;
return isAuthenticated ? (
<Outlet />
) : (
<Navigate to="/login" replace state={{ from: location }} />
);
};
export default ProtectedRoute;
检查登录并从本地存储中获取令牌,然后从登录更改链接到仪表板
builder.addCase(login.fulfilled, (state, action) => {
const isToken = localStorage.getItem("token") !== "";
const Token = localStorage.getItem("token");
history.push("/dashboard");
return {
...state,
loading: false,
isAuthenticated: isToken,
token: Token,
...action.payload,
};
});
检查路由路径并相应更改链接
<BrowserRouter>
<Routes>
<Route element={<Login />} path="/login" />
<Route path="/" element={<ProtectedRoute />}>
<Route path="dashboard" element={<Dashboard />} />
</Route>
</Routes>
</BrowserRouter>
希望这有助于解决您的问题。如果您的组件没有在登录后更改为仪表板页面,可能需要确保登录操作成功时将路由更改为仪表板页面,如上面的代码所示。
英文:
I have created a protected Route on this code
import { useSelector } from "react-redux";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { RootState } from "src/store";
const ProtectedRoute = () => {
const location = useLocation();
// const isToken = localStorage.getItem("token") !== "";
const { isAuthenticated, loading } = useSelector(
(state: RootState) => state.login
);
if (loading) return null;
return isAuthenticated ? (
<Outlet />
) : (
<Navigate to="/login" replace state={{ from: location }} />
);
};
export default ProtectedRoute;
check login and get token from localstorage and change link to dashboard from login
builder.addCase(login.fulfilled, (state, action) => {
const isToken = localStorage.getItem("token") !== "";
const Token = localStorage.getItem("token");
history.push("/dashboard");
return {
...state,
loading: false,
isAuthenticated: isToken,
token: Token,
...action.payload,
};
});
**Check Route path and change link accordingly **
<BrowserRouter>
<Routes>
<Route element={<Login />} path="/login" />
<Route path="/" element={<ProtectedRoute />}>
<Route path="dashboard" element={<Dashboard />} />
</Route>
</Routes>
</BrowserRouter>
I want to make a protected route and change login page to dashboard page when user enter correctly and everything is working perfectly but after login the url change but component did not change it will stay on login page how to change compoent to dashboard page.
答案1
得分: 0
我怀疑你已经在你的状态切片中创建了一个单独的history
对象引用,例如createBrowserHistory
,并且正在使用它来尝试导航。这显然会更新URL,但因为这发生在主应用程序路由组件之外,所以它不知道URL的更改,不会重新渲染以匹配正确的路由。
Reducer函数应被视为纯函数,没有副作用,请不要尝试从Reducer中发出导航操作。由于login
是一个异步操作,您可以在UI中使用await
来执行它,并在那里发出导航操作。
示例:
Thunk操作
const login = createAsyncAction(
"login",
async ({ username, password }, thunkAPI) => {
try {
const result = fetch(.....);
return /* auth result */
} catch(error) {
return thunkAPI.rejectWithValue(error);
}
},
);
...
builder.addCase(login.fulfilled, (state, action) => {
const token = localStorage.getItem("token");
return {
...state,
loading: false,
isAuthenticated: !!token,
token,
...action.payload,
};
});
...
登录界面
import { useNavigate } from 'react-router-dom';
...
const navigate = useNavigate();
const dispatch = useDispatch();
const loginHandler = async () => {
try {
await dispatch(login({ username, password })).unwrap();
navigate("/dashboard"); // <--- 登录后在这里导航
} catch(error) {
// 处理登录错误、拒绝的Promises等
}
};
...
英文:
What I suspect you have done is to create a separate history
object reference in your state slice, e.g. createBrowserHistory
, and are using that to try and navigate. This will obviously update the URL but because this happens outside the main app router component it isn't aware of the URL change and won't rerender with the correct route matched.
Reducer functions are to be considered pure and free of side-effects, don't try to issue a navigation action from the reducer. Since login
is an asynchronous action you can await
it in the UI and issue the navigation action there.
Example:
Thunk action
const login = createAsyncAction(
"login",
async ({ username, password }, thunkAPI) => {
try {
const result = fetch(.....);
return /* auth result */
} catch(error) {
return thunkAPI.rejectWithValue(error);
}
},
);
...
builder.addCase(login.fulfilled, (state, action) => {
const token = localStorage.getItem("token");
return {
...state,
loading: false,
isAuthenticated: !!token,
token,
...action.payload,
};
});
...
Login UI
import { useNavigate } from 'react-router-dom';
...
const navigate = useNavigate();
const dispatch = useDispatch();
const loginHandler = async () => {
try {
await dispatch(login({ username, password })).unwrap();
navigate("/dashboard"); // <-- navigate here after login resolves
} catch(error) {
// handle login errors, rejected Promises, etc
}
};
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论