You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将函数获取的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:59