成功异步操作后重定向的正确方法:将“历史”作为参数传递给 thunk VS 使用 <Redirect> 有条件地使用 Redux 存储?

问题描述 投票:0回答:1

我了解了使用 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

有谁知道这两种方法中哪一种是正确的以及为什么?

非常感谢!

reactjs redux react-redux redux-thunk react-thunk
1个回答
0
投票

如果你使用的是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);

    }
  };
}
© www.soinside.com 2019 - 2024. All rights reserved.