请教:React NavLink跳转至/addingredients时window.onload不触发的解决办法
首先明确原因:你用的是单页应用(SPA),NavLink属于前端路由跳转,不会刷新整个页面,所以window.onload这种页面级加载事件只会在首次打开或手动刷新页面时触发,路由切换时根本不会执行。
下面给你几个实用的替代方案:
方案一:利用组件生命周期钩子(最常用)
直接在/addingredients对应的组件里,通过React的生命周期钩子来触发数据获取,不管是路由跳转还是刷新页面,只要组件挂载就会执行。
函数组件(用useEffect)
import { useEffect, useState } from 'react'; function AddIngredients() { const [todos, setTodos] = useState([]); useEffect(() => { const fetchTodos = async () => { try { const res = await fetch('/todos'); const data = await res.json(); setTodos(data); } catch (err) { console.error('获取数据失败:', err); } }; fetchTodos(); }, []); // 空依赖数组确保组件挂载时仅执行一次 return ( <div> {/* 这里渲染你的todos数据 */} {todos.map(todo => <div key={todo.id}>{todo.title}</div>)} </div> ); } export default AddIngredients;
类组件(用componentDidMount)
import React, { Component } from 'react'; class AddIngredients extends Component { state = { todos: [] }; componentDidMount() { this.fetchTodos(); } fetchTodos = async () => { try { const res = await fetch('/todos'); const data = await res.json(); this.setState({ todos: data }); } catch (err) { console.error('获取数据失败:', err); } }; render() { return ( <div> {this.state.todos.map(todo => <div key={todo.id}>{todo.title}</div>)} </div> ); } } export default AddIngredients;
方案二:监听路由变化
如果需要在路由切换到/addingredients时触发逻辑,可以通过React Router的路由监听能力实现:
import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; function AddIngredients() { const [todos, setTodos] = useState([]); const location = useLocation(); useEffect(() => { // 仅当路径切换到/addingredients时执行数据获取 if (location.pathname === '/addingredients') { const fetchTodos = async () => { try { const res = await fetch('/todos'); const data = await res.json(); setTodos(data); } catch (err) { console.error('获取数据失败:', err); } }; fetchTodos(); } }, [location.pathname]); // 依赖路径变化,每次路径改变都会检查 return ( <div> {todos.map(todo => <div key={todo.id}>{todo.title}</div>)} </div> ); } export default AddIngredients;
方案三:React Router v6+ 数据路由(推荐进阶用法)
如果你用的是React Router v6及以上版本,可以用官方推荐的loader函数,在进入路由前就预加载数据:
第一步:配置路由时添加loader
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import AddIngredients from './AddIngredients'; // 定义数据加载函数 async function todosLoader() { const res = await fetch('/todos'); return res.json(); } const router = createBrowserRouter([ { path: '/addingredients', element: <AddIngredients />, loader: todosLoader, // 进入该路由时自动执行这个函数获取数据 }, ]); function App() { return <RouterProvider router={router} />; } export default App;
第二步:在组件中获取加载好的数据
import { useLoaderData } from 'react-router-dom'; function AddIngredients() { const todos = useLoaderData(); // 直接拿到loader返回的数据 return ( <div> {todos.map(todo => <div key={todo.id}>{todo.title}</div>)} </div> ); } export default AddIngredients;
内容的提问来源于stack exchange,提问作者Anh Vu
相关产品推荐
相关产品推荐

