为何setState未触发组件重渲染?React导航路径问题
问题原因及解决方案
问题原因
你的navigation状态通过useState初始化,而useState的初始值仅在组件首次渲染时计算一次。首次渲染时navPath是空字符串,因此navigation最后一项的name和href都为空。后续navPath更新后,navigation状态没有随之重新计算,组件自然不会因为navigation的变化重渲染,必须刷新页面让组件重新初始化才能看到更新后的内容。
另外,你的useEffect依赖是空数组,只会执行一次,也没有监听navPath的变化去同步更新navigation状态,这也是导航不更新的核心原因之一。
解决方案
这里提供几种可行的解决方式:
方式一:用useMemo动态生成导航数组
把navigation从状态改为基于navPath的衍生值,通过useMemo监听navPath变化,自动重新生成导航数组:
const celeb = localStorage.getItem("celeb"); const [navPath, setNavPath] = useState(""); useEffect(() => { const path = celeb === "true" ? "dashboard" : "requests"; setNavPath(path); }, []); // 依赖navPath动态生成导航数组 const navigation = useMemo(() => [ { name: "Categories", href: "#", current: false }, { name: "Home", href: "#", current: false }, { name: "How does it work", href: "#", current: false }, { name: "Celebs", href: "#", current: false }, { name: "About", href: "#", current: false }, { name: navPath, href: navPath, current: false }, ], [navPath]);
方式二:监听navPath变化更新navigation状态
如果需要把navigation存在状态中(比如后续要修改current属性),可以给useEffect添加navPath依赖,在navPath变化时同步更新导航状态:
const celeb = localStorage.getItem("celeb"); const [navPath, setNavPath] = useState(""); const [navigation, setNavigation] = useState([]); // 初始化导航路径 useEffect(() => { const path = celeb === "true" ? "dashboard" : "requests"; setNavPath(path); }, []); // 监听navPath变化,更新导航数组 useEffect(() => { setNavigation([ { name: "Categories", href: "#", current: false }, { name: "Home", href: "#", current: false }, { name: "How does it work", href: "#", current: false }, { name: "Celebs", href: "#", current: false }, { name: "About", href: "#", current: false }, { name: navPath, href: navPath, current: false }, ]); }, [navPath]);
方式三:渲染时直接动态生成(最简单)
如果仅需展示导航、不需要修改navigation的状态属性,可直接在渲染逻辑中生成导航数组,无需存入状态:
const celeb = localStorage.getItem("celeb"); const [navPath, setNavPath] = useState(""); useEffect(() => { const path = celeb === "true" ? "dashboard" : "requests"; setNavPath(path); }, []); // 渲染阶段直接生成并渲染导航 return ( <nav> {[ { name: "Categories", href: "#", current: false }, { name: "Home", href: "#", current: false }, { name: "How does it work", href: "#", current: false }, { name: "Celebs", href: "#", current: false }, { name: "About", href: "#", current: false }, { name: navPath, href: navPath, current: false }, ].map(item => ( <a key={item.name} href={item.href}>{item.name}</a> ))} </nav> );
注:你代码中的Catogories存在拼写错误,正确应为Categories,建议修正。
内容的提问来源于stack exchange,提问作者Muathcs
相关产品推荐
相关产品推荐

