React子功能组件点击新链接不重渲染、fetch不触发如何解决?
问题根因
React Router中同一路由规则匹配到相同组件时,默认会复用组件实例,不会触发卸载再挂载的生命周期。而你的Pokemon和Ability组件的useEffect都设置了空依赖数组[],只会在组件首次挂载时执行一次fetch逻辑,后续路由传入的location.state更新时,useEffect不会重新触发,因此无法拉取新数据。
修复方案
1. 补全useEffect依赖项(推荐)
给两个组件的useEffect添加上url作为依赖,当切换宝可梦导致url变化时,useEffect会自动重新执行拉取新数据。
修改Pokemon组件代码
将fetch逻辑移入useEffect内部,同时添加url为依赖:
// 先获取url再声明useEffect let props = useLocation(); // @ts-ignore let url = props.state.item.url; let [pokemon, setPokemon] = useState([]); useEffect(()=> { let fetchItems = async () => { let data = await fetch(url); let items = await data.json(); setPokemon(items); } fetchItems().then(r => console.log("got pokemon details")) },[url]) // 依赖项添加url,url变化自动重新执行
修改Ability组件代码
同理调整useEffect和依赖:
// 先获取url再声明useEffect let props = useLocation(); // @ts-ignore let url = props.state.item.url; let [abilities, setAbilities] = useState([]); useEffect(()=> { let fetchAbilities= async () => { let data = await fetch(url); let items = await data.json(); let abilities1 = items.abilities; let denormalized = { "name":"", "abilities": [] } for(let i = 0; i< abilities1.length; i++){ let abilityUrl = abilities1[i].ability.url let response = await fetch(abilityUrl); let promise = await response.json(); denormalized.name = promise.names; // @ts-ignore denormalized.abilities.push(promise) } // @ts-ignore setAbilities(denormalized); } fetchAbilities().then(r => console.log("got getting ability")) },[url]) // 依赖项添加url
2. 修正路由拼写错误
你代码中跳转Ability的路径写的是/component/abilities/Ability,而Route匹配规则是/components/:repo,路径少了一个s,需要统一路径拼写,否则路由无法正确匹配。
可选方案:强制组件重挂载
如果不想修改依赖逻辑,也可以给Route添加key属性,属性值绑定当前路由路径,路由变化时会强制销毁旧组件实例,挂载新的组件实例,自然会重新触发useEffect:
<Route path="/components/pokemon/" component={Pokemon} key={window.location.pathname} />
内容的提问来源于stack exchange,提问作者notin
相关产品推荐
相关产品推荐

