如何将函数获取的blogId变量传递给React组件?
解决Next.js中组件间路由参数传递的问题
这个问题我太熟了,咱们一步步拆解解决:
首先得明确核心问题:你的BlogPost函数组件和Home类组件是两个独立的作用域,blogId是BlogPost内部的变量,Home根本访问不到它;而且类组件没法直接使用useRouter这种React Hooks,这就是为什么你用变量时会报blogId is not defined的原因。
下面给你两种可行的解决方案,优先推荐第一种,更符合Next.js的现代开发习惯:
方案一:把Home改成函数组件(推荐)
直接将类组件转换为函数组件,这样就能直接使用useRouter钩子获取blogId,不用额外传参,代码更简洁易维护:
import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; function Home() { // 用useState管理状态 const [post, setPost] = useState({}); const [isLoaded, setIsLoaded] = useState(false); // 获取路由参数 const router = useRouter(); const blogId = router.query.id; // 用useEffect替代componentDidMount useEffect(() => { // 重要:router.query.id在页面刚加载时可能为undefined,必须先判断再发起请求 if (blogId) { fetch(`http://localhost/wordpress/index.php/wp-json/wp/v2/featured_item/${blogId}`) .then(postsResponse => postsResponse.json()) .then((fetchedPost) => { setPost(fetchedPost); setIsLoaded(true); }); } }, [blogId]); // 依赖blogId,当路由参数变化时自动重新请求 // 渲染逻辑和之前一致 if(isLoaded){ return ( <motion.div initial="initial" animate="enter" exit="exit" variants={portfolioVariants}> <Posts post={post}/> </motion.div> ) }else{ return( <Loader /> ) } } export default Home;
方案二:保留类组件,通过Props传递blogId
如果你一定要保留Home作为类组件,那需要在父组件BlogPost中拿到blogId,再通过props传递给Home组件:
第一步:修改BlogPost组件,传递props
function BlogPost() { const router = useRouter(); const blogId = router.query.id; // 将blogId作为props传给Home组件 return <Home blogId={blogId} />; }
第二步:修改Home类组件,接收并使用props
class Home extends React.Component { state = { post: {}, isLoaded: false }; componentDidMount() { // 从props中获取blogId const { blogId } = this.props; // 同样要先判断blogId是否存在 if (blogId) { fetch(`http://localhost/wordpress/index.php/wp-json/wp/v2/featured_item/${blogId}`) .then(postsResponse => postsResponse.json()) .then((post) => { this.setState({ post, isLoaded: true }) }); } } // 可选:如果路由参数可能动态变化,需要监听props更新 componentDidUpdate(prevProps) { if (this.props.blogId !== prevProps.blogId) { // 重置加载状态,重新请求数据 this.setState({ isLoaded: false }); fetch(`http://localhost/wordpress/index.php/wp-json/wp/v2/featured_item/${this.props.blogId}`) .then(postsResponse => postsResponse.json()) .then((post) => { this.setState({ post, isLoaded: true }) }); } } render() { const { post, isLoaded } = this.state; if(isLoaded){ return ( <motion.div initial="initial" animate="enter" exit="exit" variants={portfolioVariants}> <Posts post={post}/> </motion.div> ) }else{ return( <Loader /> ) } } }
这里要纠正你之前的错误:你之前直接在Home的state里写id: blogId是没用的,因为blogId不在Home的作用域内;而且componentDidMount不接收参数,所以那样写根本拿不到值。必须通过props从父组件传递过来才能访问。
内容的提问来源于stack exchange,提问作者Dmitry Raskopin
相关产品推荐
相关产品推荐

