将 react router V6 导航与 redux 和 redux thunk 操作一起使用的最佳方法是什么?
what is the best way to use react router V6 navigation with redux and redux thunk actions?
我正在使用 React-v17 和 react-redux V7 制作一个 React 应用程序(不是 react-native),以及 React Router V6,
搜索和阅读许多文章,我找不到使用 V6 挂钩在 redux 操作中以编程方式导航的方法,因为挂钩只能在组件内部调用,这就是我所拥有的
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>
)
}
在我的状态管理模块中,我创建了一个调度 API 动作的函数,什么
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))
},
})
}
正如我评论的那样,我想在“onSuccessFunc”内的那个动作中执行一个函数,以便它将用户带到一个特定的页面
,
我知道我可以制作一个减速器并将其用于导航,我将带有有效负载的操作发送到我想要导航的位置,并且在 HOC 中,我检查是否有导航路径,
如果我是真的,我会清除它并导航,就像这样!
let navigation = useSelector((state) => state.navigation)
useEffect(() => {
if (navigation.path) {
dispatch(
navigationActions.CLEAR_NAVIGATION_PATH()
)
navigate('/navigation.path')
}
}, [])
这似乎是一个很好的解决方案,我认为可能会有很多 DRY 和缺点,
做这个的最好方式是什么!你看到我的解决方案有什么缺点了吗!记住我使用的是 react-router V6!谢谢。
您最好直接在回调中进行导航。
您可以利用 Hooks 的规则:Call Hooks from custom Hooks.
// register.js or useRegister.js
export const useRegisterUser = () => {
const navigate = useNavigate();
const doRegister = (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())
// allowed since it's inside a hook
navigate("menu")
},
onErrorFunc: (error) => (dispatch, store) => {
dispatch(ADD_MAIN_ERROR(error))
},
})
}
return {
doRegister
}
}
// registerPage.js
import { useRegisterUser } from './register.js'
// other imports
const RegisterForm = (props) => {
const { doRegister } = useRegisterUser()
// other stuffs
// grab credentials
dispatch(doRegister(credentials))
// other stuffs
return (<></>)
}
在搜索和阅读一些评论后,我找到了 3 种可能的解决方案,
第一个是第一个答案,但我不太习惯使用它,因为我不知道钩子的实现细节,我试过了,效果很好,
第二个选项是创建您自己的 CustomRouter
,给它一个您创建的 history
对象,然后按照此处指定的方式更改您创建的历史对象:
,感谢 Drew 指出。
第三是使用一个你可以从 RRDv6 导入的对象,叫做 unstable_HistoryRouter
,你也可以在这里找到它 .
我正在使用 React-v17 和 react-redux V7 制作一个 React 应用程序(不是 react-native),以及 React Router V6, 搜索和阅读许多文章,我找不到使用 V6 挂钩在 redux 操作中以编程方式导航的方法,因为挂钩只能在组件内部调用,这就是我所拥有的
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>
)
}
在我的状态管理模块中,我创建了一个调度 API 动作的函数,什么
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))
},
})
}
正如我评论的那样,我想在“onSuccessFunc”内的那个动作中执行一个函数,以便它将用户带到一个特定的页面 , 我知道我可以制作一个减速器并将其用于导航,我将带有有效负载的操作发送到我想要导航的位置,并且在 HOC 中,我检查是否有导航路径, 如果我是真的,我会清除它并导航,就像这样!
let navigation = useSelector((state) => state.navigation)
useEffect(() => {
if (navigation.path) {
dispatch(
navigationActions.CLEAR_NAVIGATION_PATH()
)
navigate('/navigation.path')
}
}, [])
这似乎是一个很好的解决方案,我认为可能会有很多 DRY 和缺点, 做这个的最好方式是什么!你看到我的解决方案有什么缺点了吗!记住我使用的是 react-router V6!谢谢。
您最好直接在回调中进行导航。 您可以利用 Hooks 的规则:Call Hooks from custom Hooks.
// register.js or useRegister.js
export const useRegisterUser = () => {
const navigate = useNavigate();
const doRegister = (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())
// allowed since it's inside a hook
navigate("menu")
},
onErrorFunc: (error) => (dispatch, store) => {
dispatch(ADD_MAIN_ERROR(error))
},
})
}
return {
doRegister
}
}
// registerPage.js
import { useRegisterUser } from './register.js'
// other imports
const RegisterForm = (props) => {
const { doRegister } = useRegisterUser()
// other stuffs
// grab credentials
dispatch(doRegister(credentials))
// other stuffs
return (<></>)
}
在搜索和阅读一些评论后,我找到了 3 种可能的解决方案,
第一个是第一个答案,但我不太习惯使用它,因为我不知道钩子的实现细节,我试过了,效果很好,
第二个选项是创建您自己的 CustomRouter
,给它一个您创建的 history
对象,然后按照此处指定的方式更改您创建的历史对象:
unstable_HistoryRouter
,你也可以在这里找到它