首页 > 解决方案 > 当我需要从 Link 组件中获取路径名道具时,我可以使用 useEffect 钩子和函数组件吗?

问题描述

这些天我开始学习 React.js。

我想知道是否可以使用useEffect钩子和函数组件而不是componentDidMount()类组件,例如,当用户直接转到“http://localhost:3000/movie-detail”而不单击“电影”链接时。

我尝试了一些方法,我认为,在这种情况下,我必须使用componentDidMount()和类组件,因为必须单击“电影”链接才能传递props给“详细信息”组件。

如果您知道如何处理此问题,请告诉我,好吗?



这是我的“电影”组件,其中有一个路径名道具。

function Movie({id, year, title, summary, poster, genres}){
    return (
        <Link
          to={{
            pathname:"/movie-detail",
            state: {
                year,
                title,
                summary,
                poster,
                genres
            }
          }}
         >
           <div className="movie">
                ...
           </div>
       </Link>
    )
}



这是我的“应用程序”组件,其中将路径名道具传递给“详细信息”组件。

function App() {
  return (
    <BrowserRouter>
      <Navigation />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/movie-detail" component={Detail} />
      </Switch>
    </BrowserRouter>
  )
}



这是我的“详细信息”组件,其中获取表单 Route 组件的道具。

function Detail({location, history}) {

  useEffect(() => {
     if(location === undefined) {
       history.push("/");
     }
   }, [ location, history])

  const { title } = location.state;

  return (
   <h1>Title: {title}</h1>
  )
}



我得到如下错误代码。

TypeError: Cannot destructure property 'title' of 'location.state' as it is undefined.

标签: javascriptreactjsuse-effect

解决方案


修改路由路径到 /movie-detail/:id ,刷新页面时,可以从服务器加载电影数据

function Movie({id, year, title, summary, poster, genres}){
    return (
        <Link
          to={{
            pathname:"/movie-detail/" + id,
            state: {
                year,
                title,
                summary,
                poster,
                genres
            }
          }}
         >
           <div className="movie">
                ...
           </div>
       </Link>
    )
}

function App() {
  return (
    <BrowserRouter>
      <Navigation />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/movie-detail/:id" component={Detail} />
      </Switch>
    </BrowserRouter>
  )
}

function Detail({location}) {

  
  const [state, setState] = useState(location && location.state);
  const id = location && location.params.id;
  useEffect(()=> {
    if (id){
      fetch('/api/movie/' + id)
         .then((x)=> x.json())
         .then((x)=> setState(x));
    }
  }, [!state, id])
  if (!location || !id){return <Redirect to="/" />}
  if (!state) return <div>Loading.....</div>
  return (
   <h1>Title: {state.title}</h1>
  )
}

推荐阅读