1

So, I'm having a bit of an issue when it comes to routing and managing my data.

The Listing component is essentially a ton of cards with movie data that I am fetching from a gist of mine. I created a component for each card using .map and adding the value to the prop.

My goal: When I click a button for any of the cards, I would like to go to a page and access that movie card's name dynamically.

For Example:: Suppose I click on a button that says "MoreInformation" for one particular movie card. I get routed to the MoreInformation page because the button will be contained in a Link.

Inside the MoreInformation Page/Component I would like to dynamically add:

<h1>{name}</h1>

This is just a basic example of what I am trying to accomplish, but in other words how do I transfer the data of that particular movie card to the MoreInformation page so that I can access it to add dynamic data.

I will be extremely grateful if I can get feedback as this project is time sensitive... Thanks guys.

const MoviesPage = () => {
  const [movies, setMovies] = useState([])

  useEffect(() => {
    axios
      .get(
        `https://gist.githubusercontent.com/ernestosotelo/9932c659b460e5ddeec8a8ae76164a0d/raw/ce8d7b248f61e73bf3c767538728505d6bac9835/json`
      )
      .then(res => {
        const data = res.data
        setMovies(data)
      })
  }, [])

  return (
    <Layout>
      <div style={{ background: "hsl(215, 100%, 3%" }}>
        <TopThree />

        <p style={{ color: "#e0dfe2", fontSize: "1.7rem", marginTop: "3rem" }}>
          <b
            style={{
              padding: ".5rem 1.5rem .5rem 1.5rem",
              background: "#f9ba00",
              fontSize: "2rem",
              marginLeft: "4rem",
              color: "black"
            }}
          >
            !
          </b>{" "}
          Click 'Remove' to remove movies you definitely will not watch! There
          is an undo option.
        </p>

        <div className={listingCSS.block}>
          {movies.map(movie => {
            return (
              <Listing
                key={movie.name}
                name={movie.name}
                plot={movie.plot}
                date={movie.releaseDate}
                genre={movie.genre}
                imdbRating={movie.imdbRating ? movie.imdbRating : "N/A"}
                tomatoRating={movie.tomatoRating ? movie.tomatoRating : "N/A"}
                metaRating={movie.metaRating ? movie.metaRating : "N/A"}
                erbertRating={movie.erbertRating ? movie.erbertRating : "N/A"}
                tmdbRating={movie.tmdbRating ? movie.tmdbRating : "N/A"}
                movshoRating={movie.movshoRating}
                streamOn={movie.streamOn}
                poster={movie.poster}
                alt={movie.name}
              />
            )
          })}
        </div>
      </div>
    </Layout>
  )
}
Ernie
  • 186
  • 1
  • 1
  • 10
  • You can add unique identifiers to each movie and pass that identifier to the other page through the URL. On the other page just retrieve the appropriate movie's details from the server or some kind of in memory/local storage. – Titus May 12 '19 at 08:50
  • I think this other post is a complement to how it works. https://stackoverflow.com/questions/55219775/cant-pass-state-with-link-compoment-why-is-state-undefined – Erick Sep 17 '21 at 21:24

2 Answers2

2

You need to create a route for displaying the data passed. For example

<Route path="/movieInfo/:name" exact component={MoreInformation} />

In your listing create a link to more information component

<Link to={`/movieInfo/${this.props.name}`}>More info</Link>

In your MoreInformation component access the prop like

const { name } = this.props;

Simple Demo here

If you are using functional components, you can retrieve the value, like below. Inside match params.

function MoreInformation(props) {

  const name = props.match.params.name;

  return <h1>{name}</h1>;
}
Junius L
  • 15,881
  • 6
  • 52
  • 96
  • Thanks for trying. Unfortunately, that didn't work. I receive "Cannot read property 'props' of undefined". I am also not using class-based components, only functional components. Your code architecture is definitely different than mine. I have been able to pass via the link the movie name because the URL definitely displays the movie I click on, but I am unable to access that data on the new page using your recommendation. – Ernie May 12 '19 at 21:08
  • can you please share your component – Junius L May 12 '19 at 21:17
  • see my updated answer, on how to access the value inside a functional prop. – Junius L May 12 '19 at 21:33
  • You did it! I didn't even have to post my terrible React architecture. I am still learning my way with React, so I appreciate it. Thanks a lot, and I am eternally grateful. If you have the time, would you explain like I am 5 years old how props.match.params.name worked for me in this case. – Ernie May 12 '19 at 21:54
  • please go through this tutorial https://tylermcginnis.com/react-router-pass-props-to-link will help you understand more. with function component you can access the values with `props.value` but when using `Link` you need to get the values from match object. – Junius L May 12 '19 at 21:57
  • What if I wanted to pass a JSON Object? would this be an ideal method? – chobela Aug 15 '22 at 02:07
0

You could use JS with HTML 5 elements to store the data on session (sessionStorage.getItem() and sessionStorage.setItem()) or locally (localStorage.getItem() and localStorage.setItem()).

If you prefer storing the data on setItem by variables :

var session_data = sessionStorage.myValue //For session only
var local_data = localStorage.myValue //For local

sessionStorage.myValue = 'value' //For session only
localStorage.myValue = 'value' //For local

Remember also : To store JavaScript objects you should set and change them to a string value :

sessionStorage.myObject = JSON.stringify(myObject); // Setting the object to a string

And parsing it back to object to retrieve the data when using getItem :

var myObject = JSON.parse(sessionStorage.myObject); // Parsing JSON back from string to object

ALSO : You could use window.name to store information, but note that it works only when the same window/tab is used, so make sure your button or link has the target value set to _self.

You can read about storing data without cookies with JavaScript HERE

For info about the Web Storage API : https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API

For info about PersistJS (might interest you) : https://github.com/jeremydurham/persist-js

mattdaspy
  • 842
  • 1
  • 5
  • 11
  • Thanks, I considered a localStorage approach but I know this would not be the best use case for my scenario, and it kind of complicates the architecture more than it already is since I am still finding my way with React. – Ernie May 12 '19 at 21:10