我了解了使用 Redux Thunk 执行异步操作后重定向到不同页面的 2 种方法:
1-方法:将“历史”对象作为参数传递给异步操作。
在您的组件中,您使用“useHistory”钩子定义“history”对象并将其传递给您的异步操作:
function Register(){
const history = useHistory()
const dispatch = useDispatch()
function registerHandler(){
dispatch(registerAsync(registerForm, history))\
}
return (
// JSX Code
<button onClick={registerHandler}>Register</button>
)
}
然后在异步操作中,您可以使用“history.push()”来重定向:
export function registerAsync(data, history){
return async function (dispatch) {
try {
const response = await Axios.Post('api/register/', data)
history.push('/register_success')
} catch (e) {
dispatch(registerError(e))
}
}
}
2-方法:使用根据 Redux 存储值有条件渲染的 < Redirect > 组件:
在组件中,如果存储值为 true,则有条件地返回:
function Register(){
const dispatch = useDispatch()
const registerSuccess = useSelector((store) => store.auth.registerSuccess)
function registerHandler(){
dispatch(registerAsync(registerForm, history))\
}
if (registerSuccess) {
return <Redirect push to="/register_success"/>
}
return (
// JSX Code
<button onClick={registerHandler}>Register</button>
)
}
在我们的异步操作中,我们调度一个将“registerSuccess”设置为 true 的操作:
export function registerAsync(data){
return async function (dispatch) {
try {
const response = await Axios.Post('api/register/', data)
dispatch(registerSuccess())
} catch (e) {
dispatch(registerError(e))
}
}
}
减速机:
case actionTypes.REGISTER_SUCCESS:
newState.registerSuccess = true
return newState
有谁知道这两种方法中哪一种是正确的以及为什么?
非常感谢!
如果你使用的是react-router-dom v6,那么你应该使用useNavigate而不是useHistory,如本例所示
https://stackoverflow.com/a/63921034/13218213
虽然我通过将
navigate
函数传递给处理程序找到了一个很好的解决方案(在我的例子中,我将其传递给 asyncAction 函数
MyComponent.tsx
import {useNavigate} from 'react-router-dom';
import {useAppDispatch, actions } from 'store';
const MyComponent = () => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const handleConfirm = () => {
dispatch(actions.slice.asyncActionFunction(navigate));
};
return <></>
};
然后在 asyncAction (或 asyncThunk)中我这样做了
async-actions.ts
import { NavigateFunction } from 'react-router-dom';
export function asyncActionFunction(navigate: NavigateFunction) {
return async (dispatch: AppDispatch, getState: () => RootState) => {
try{
/**
* you can now use navigate(to:string; options: {}) as following
*/
navigate('/destination');
} catch (e) {
console.error(e);
}
};
}