Search code examples
javascriptreactjsgraphqlrelayjs

Nested React/Relay component not receiving props


I'm trying to pass an attribute into another component. Passing the array as <VideoList videos={this.props.channel.video_list}></VideoList> results in this.props.videos being an empty object:

{
  "videos": {
    "__dataID__": "client:5610611954",
    "__fragments__": {
      "2::client": "client:5610611954"
    }
  }
}

(GraphQL returns the correct data as confirmed by the React Chrome extension, it's just not being passed into the VideoList.)

components/video_list.js

import React from 'react'
import Relay from 'react-relay'
import VideoItem from '../containers/video_item'    

export default class VideoList extends React.Component {
  render() {
    return(
      <div>
      {
        this.props.videos.edges.map(video =>
          <VideoItem key={video.id} video={video.node}/>
        )
      }
      </div>
    )
  }
}

components/channel_list.js

import React from 'react'
import Relay from 'react-relay'
import VideoList from './video_list'

export default class ChannelView extends React.Component {
  render() {
    return(
      <div>
        <Column small={24}>
          <h2>{this.props.channel.title}</h2>
        </Column>

        <VideoList videos={this.props.channel.video_list}></VideoList>
      </div>


    )
  }
}

containers/channel_list.js

import React from 'react'
import Relay from 'react-relay'
import ChannelView from '../components/channel_view'
import VideoList from './video_list'

export default Relay.createContainer(ChannelView, {
  fragments: {
    channel: () => Relay.QL`
      fragment on Channel {
        title
        video_list {
          ${VideoList.getFragment('videos')}
        }
      }`
  },
});

containers/video_list.js

import React from 'react'
import Relay from 'react-relay'
import VideoList from '../components/video_list'
import VideoItem from './video_item'

export default Relay.createContainer(VideoList, {
  initialVariables: {
    count: 28
  },
  fragments: {
    videos: () => Relay.QL`
      fragment on Videos {
        videos(first: $count) {
          pageInfo {
            hasPreviousPage
            hasNextPage
          }
          edges {
            node {
              ${VideoItem.getFragment('video')}
            }
          }
        }
      }`
  },
});

What am I doing wrong? Am I misunderstanding how Relay works? I want to be able to set the count relay variable in the VideoList for pagination purposes. The VideoList object is going to be nested within multiple other components (e.g. channel, most popular, user's favorites, etc.)

Thank you!


Solution

  • You are trying to use the VideoList component directly, without the relay container wrapping it, and that's wrong. You need to use the VideoList wrapped version - the one you are exporting in ./containers/video_list.js.

    Like this:

    import React from 'react'
    import Relay from 'react-relay'
    import VideoList from '../containers/video_list'
    
    export default class ChannelView extends React.Component {
      render() {
        return(
          <div>
            <Column small={24}>
              <h2>{this.props.channel.title}</h2>
            </Column>
    
            <VideoList videos={this.props.channel.video_list}></VideoList>
          </div>
    
    
        )
      }
    }