React道具在传递时会串联在一起

时间:2020-08-01 12:43:56

标签: reactjs typescript

我有一个相当深的嵌套react组件,我想在其中使用道具来访问道具movie,我必须遍历一个嵌套的烂摊子:

const removeMovieFromDashboard = (movie) => {

  const removeMovieFromList = async (movie) => {
    const value = await localforage.getItem<any []>('trackedMovies');
    value.forEach((item, index) => {
      console.log(item.id === movie.movie.movie.movie.id)
      if (item.id === movie.movie.movie.movie.id) {
        value.splice(index, 1);
        localforage.setItem('trackedMovies', value)
      }
    })
  }

  return (
    <div onClick={() => removeMovieFromList(movie)}>Remove movie</div>
  )
}

如您所见,我必须遍历3个电影对象才能获得ID movie.movie.movie.movie.id。我很确定React比那聪明,所以我做错了事。

这是我正在使用的结构:

MovieOverview通过MovieContext接收一系列电影,并通过每个电影的映射创建一个子组件:

let [movies, setMovies] = useContext(MovieContext)

return (
  <ul>
    { movies ? movies.map(movie => (
      <MovieOnDashboard movie={movie}/>
    )) : null}
  </ul>
)

MovieOnDashboard接受向下传递的道具,并呈现一个OverlayEL组件,该组件也接受该道具。

const OverlayEl = (props) => {
  return (
    <Overlay>
      <RemoveMovieFromDashboard movie={props}/>
    </Overlay>
  )
}

const MovieOnDashboard = (movie) => {

  const imagePath = 'https://image.tmdb.org/t/p/w185/'
  const [isHover, setHover] = useState(false);

  return (
    <MovieContainer 
      key={movie.movie.id}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}>
        <img src={imagePath + movie.movie.poster_path} alt='poster' />
      { isHover && <OverlayEl movie={movie} />}      
    </MovieContainer>
  )
}

OverlayEl呈现了我开始发布帖子的另一个组件RemoveMovieFromDashboard。这样movie道具就传了好几次。

当我通过组件树传递道具时,有没有办法不让它们堆叠/串联?

1 个答案:

答案 0 :(得分:1)

功能组件将props对象作为参数而不是电影作为对象。

MovieOnDashboard中,您正在调用props对象(它将包含键moviemovie。这就是为什么您必须要做movie.movie之类的事情。

当您呼叫<OverlayEl movie={movie} />时,movie不会是电影,而是包含电影的道具对象。这就是为什么您的嵌套孩子必须做movie.movie.movie...

您可以这样重新排列代码:

const MovieOnDashboard = ({ movie }) => { // we deconstruct the props to extract the movie

  const imagePath = 'https://image.tmdb.org/t/p/w185/'
  const [isHover, setHover] = useState(false);

  return (
    <MovieContainer 
      key={movie.id}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}>
        <img src={imagePath + movie.poster_path} alt='poster' />
      { isHover && <OverlayEl movie={movie} />}      
    </MovieContainer>
  )
}

别忘了更新您的所有组件。