I am making a react app (not react-native) using React-v17, and react-redux V7, and React Router V6, searching and reading many articles, I could not find a way to navigate programmatically inside redux actions using the V6 hooks, as hooks can only be called inside components, here is what I have
registerPage.jsx
import React, { Component } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { LockClosedIcon } from '@heroicons/react/solid'
import Loader from 'react-loader-spinner'
import { registerUser } from '../../../state_man/store/register'
const RegisterForm = (props) => {
const [registerFields, setRegisterFields] = useState({})
const [errors, setErrors] = useState({})
const [validInput, setValidInput] = useState({})
const [loading, setLoading] = useState(false)
let navigate = useNavigate()
let params = useParams()
let auth = useSelector((state) => state.auth)
let mainUi = useSelector((state) => state.UI.mainUI)
let registerUi = useSelector((state) => state.UI.registerPage)
const dispatch = useDispatch()
const { isLoggedIn } = auth
const onRegisterUser = (e) => {
e.preventDefault()
const credentials = {
username: registerFields['username'],
['phone']: registerFields['phone'],
email: registerFields['email'],
region: registerFields['region'],
password: registerFields['password'],
address: registerFields['address'],
client_name: registerFields['client_name'],
}
dispatch(registerUser(credentials))
return (
// my form is so long, i made it short just for demonstration purposes!
<form>
<input type='text' />
<input type='passowrd' />
<button
onClick={(e) => {
// here i call the function that does the registration ,
//that included calling a function that dispatches API action,
onRegisterUser(e)
}}
></button>
</form>
)
}
in my state management module, I create a function that dispatch API actions, what
register.js
const url = '/client'
export const registerUser = (credentials) => {
return apiActionCreators.apiCallBegan({
url,
method: 'post',
data: credentials,
onStart: START_LOADING.type,
onEnd: END_LOADING.type,
onSuccessFunc: (data) => (dispatch, store) => {
dispatch(USER_REGISTERED(data))
dispatch(CLEAR_MAIN_ERROR())
// i want to take the user to a specific page using something like navigate("menu")
},
onErrorFunc: (error) => (dispatch, store) => {
dispatch(ADD_MAIN_ERROR(error))
},
})
}
as I commented, I want to execute a function in that action inside "onSuccessFunc" so that it takes the user to a specific page , i know i can make a reducer and use it for navigation, i send action with a payload to where i want to navigate, and in a HOC, i check if there is a path to navigate to, if i true, i clear it and i navigate , some thing like this !
let navigation = useSelector((state) => state.navigation)
useEffect(() => {
if (navigation.path) {
dispatch(
navigationActions.CLEAR_NAVIGATION_PATH()
)
navigate('/navigation.path')
}
}, [])
this does seem to be a good solution, and i think there can be a lot of DRY and shortcomings, what is the best way to do this! and do you see any shortcomings in my solution!, remember i am using react-router V6! thanks.