0

I have started learned React.js these days.

I am wondering if I can use the useEffect hook and function component instead of componentDidMount() and class component, for example, when users go to DIRECTLY "http://localhost:3000/movie-detail" without clicking on "movie" Link.

I tried some way and I think, in this case, I have to use componentDidMount() and class component because the "Movie" Link must click on to pass props to the "Details" component.

If you know how to handle this problem can you let me know, please?



Here is my "Movie" component where has a pathname 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>
    )
}



Here is my "App" component where passes the pathname props to a "Detail" component.

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



Here is my "Detail" component where gets props the form Route component.

function Detail({location, history}) {

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

  const { title } = location.state;

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



And I got error code like this below.

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

Rebai Ahmed
  • 1,509
  • 1
  • 14
  • 21

2 Answers2

0

I believe the issue here is not with the way you could use the useEffect, but to answer your question, yes you could definitely use, useEffect in the functional component, in place of componentDidMount.

If we look into the Error, your code is throwing it because it cannot receive the value in the location variable, hence it is not possible to restructure that value.

The Link which we are using in react is in fact similar to anchor tags in HTML.We could use the same in react as well, but the reason for avoiding them is because they will re-render your complete page, and react library rerenders only those parts in the page, which are changed, the rest remains the same. Hence we do not prefer using anchor tags in react. You could read further about the same from the following Link:- https://www.pluralsight.com/guides/understanding-links-in-reactjs All the data passed in the to object is received in props:- You could follow the following link:-https://stackoverflow.com/questions/30115324/pass-props-in-link-react-router , https://medium.com/@bopaiahmd.mca/how-to-pass-props-using-link-and-navlink-in-react-router-v4-75dc1d9507b4

Now, I believe your could refactor your code in the following way:-

function Detail(props) {

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

  const { title } = props.location.state;

  return (
   <h1>Title: {title}</h1>
  )
}
Shubhra Kushal
  • 311
  • 1
  • 5
  • Thank you for answering me. I tried it but it still didn't work. I will go for the liink you gave me as references. :- ) – loocia kim May 26 '21 at 00:45
0

modify route path to /movie-detail/:id , when refresh page, can load movie data from server

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>
  )
}
欧阳斌
  • 2,231
  • 1
  • 8
  • 8
  • Thank you. I tried it . but it still is not working. I got error like this "TypeError: Cannot read property 'id' of undefined" eventhough I add id props to the "state" object in the Movie component. But I think I can figure out with the Redirect , useLocation or useHistory. – loocia kim May 26 '21 at 14:24