React Router同页面提交表单后Redirect无效,如何重新渲染组件?
解决React Router表单提交后同一页面组件不重新渲染的问题
方案1:用revalidatePath强制触发路径验证
React Router v6.4+提供了revalidatePath方法,能强制指定路径的loader重新执行,从而刷新页面数据并重新渲染组件。
修改Home.tsx中的action函数:
import { json, redirect, revalidatePath } from 'react-router-dom' export const action = async ( { request } ) => { const data = await request.formData() const measuramentData: Wines = { // 你的数据结构 } const currentHost = getCurrentHost() const token = getAuthToken() const response = await fetch( currentHost + 'measuraments', { method: 'POST', headers: { 'Content-type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify(measuramentData) }) // 强制重新验证根路径,触发对应loader重新获取数据 revalidatePath('/') return redirect('/') }
只要Measuraments组件依赖的是路由loader返回的数据,这一步就能自动让它重新渲染。
方案2:让组件监听action状态主动刷新
如果Measuraments是自己内部请求数据,就可以利用useNavigation监听action的执行状态,触发组件重新拉取数据。
首先修改Home.tsx:
import { useNavigation } from 'react-router-dom' import Measuraments from '@components/Measuraments/Measuraments' import NewMeasurament from '@components/Measuraments/NewMeasurament' export const Home = () => { const navigation = useNavigation() // 标记action是否刚执行完成 const shouldRefresh = navigation.state === 'idle' && navigation.formData !== null return ( <> <NewMeasurament /> <Measuraments shouldRefresh={shouldRefresh} /> </> ) }
然后在Measuraments.tsx中监听状态变化:
import { useEffect, useState } from 'react' import { getAuthToken } from '@util/auth' import getCurrentHost from '@util/host' const Measuraments = ({ shouldRefresh }) => { const [measurements, setMeasurements] = useState([]) const fetchMeasurements = async () => { const token = getAuthToken() const currentHost = getCurrentHost() const res = await fetch(`${currentHost}measuraments`, { headers: { 'Authorization': `Bearer ${token}` } }) const data = await res.json() setMeasurements(data) } // 初始化和状态变化时重新请求数据 useEffect(() => { fetchMeasurements() }, [shouldRefresh]) return ( {/* 渲染你的列表内容 */} <div>{measurements.map(item => <div key={item.id}>{item.name}</div>)}</div> ) } export default Measuraments
方案3:通过action返回数据触发刷新
在action中返回提交结果,组件通过useActionData获取状态,进而触发Measuraments刷新。
修改Home.tsx的action:
export const action = async ( { request } ) => { // ... 之前的请求逻辑 const response = await fetch(...) if (response.ok) { return json({ success: true }) } else { return json({ success: false, error: '提交失败' }, { status: 400 }) } }
然后更新Home.tsx组件:
import { useActionData } from 'react-router-dom' export const Home = () => { const actionResult = useActionData() return ( <> <NewMeasurament /> <Measuraments refreshOnSuccess={actionResult?.success} /> </> ) }
Measuraments组件的逻辑和方案2一致,监听refreshOnSuccess的变化重新请求数据即可。
内容的提问来源于stack exchange,提问作者Sky
相关产品推荐
相关产品推荐

