Home > Blockchain >  Composing React Components for Reusability
Composing React Components for Reusability

Time:10-23

I am working on a ReactJS app to display the movies and sort them in ascending and descending order. I have App.js component, which loads the movies from an API and then sends the movies to MovieList component.

function App() {

  const [movies, setMovies] = useState([])

  useEffect(() => {
    fetchMovies() 
  }, [])

  const fetchMovies = async () => {
    let response = await fetch('SOMEURLTOMOVIES')
    let result = await response.json() 
    setMovies(result.Search)
  }

  const handleSort = () => {
    let sortedMovies = movies.sort((a, b) => {
      return b.Title - a.Title 
    })

    console.log(sortedMovies)
  }

  return (
    <div className="App">
      <button onClick = {handleSort}>Sort</button>
        <MovieList movies = {movies} />
    </div>
  );
}

export default App;

The MovieList component is shown below:

function MovieList(props) {

  const movieItems = props.movies.map((movie) => {
    return <li key = {movie.imdbID}>{movie.Title}</li>
  })

  return (
    <div>
      {movieItems}
    </div>
  )

}

The movies are displayed correctly. The first thing to notice is that the fetchMovies is right inside the Component. I see this pattern in most of React apps. What if they want to perform fetchMovies from somewhere else. I guess devs will then move it into a separate function etc.

Another thing about App.js function is the sort function (currently not working). Only App component can sort the movies. What if some other component is also interested in sorting the movies? How would we do that?

CodePudding user response:

Firstly it depends on the goals. If you are trying to make it so the movies are only fetched once and all components use the data from that fetch, you will use React Context. However, context shouldn't be used as a get-out-of-jail-free card when you need only code re-use and not shared state.

Typically, for code reuse purposes, you'd put this logic in a custom hook.

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

  useEffect(() => {
    fetchMovies() 
  }, [])

  const fetchMovies = async () => {
    let response = await fetch('SOMEURLTOMOVIES')
    let result = await response.json() 
    setMovies(result.Search)
  }

  const sort = () => {
    let sortedMovies = movies.sort((a, b) => {
      return b.Title - a.Title 
    })

    return sortedMovies 
  }

  return { movies, sort } 
}
  • Related