0

I'm new to Reactjs. I'm trying to make a story player (like audio player but with stories).

https://i.stack.imgur.com/WX6sI.jpg

render() {
    const storiesList = this.props.stories;
    return(
        <div>
            {
                storiesList.map((story, k) => {
                return(
                    <div
                        ref={this.myRef}
                        key={k}
                        className="story"
                        onClick={() => this.playAudio(story.playing_url)}
                        onChange={console.log(this.myRef.current)}
                    >
                        <img 
                            src={story.image_url}
                            className="story-img"
                            alt="story"
                        />
                        <div className="story-play">
                            <div className="story-play-inner">
                            {
                                this.state.playing_story === story.playing_url && this.state.playing
                                ? <span>&#124; &#124;</span>
                                : <span>&#9654;</span>
                            }
                            </div>
                        </div>
                        <p className="story-name">
                            {story.name}
                        </p>

                    </div>
                )
            })}
            <div className="progress-bar" >

            <div className="playBtn">
                <span>&#9654;</span>
            </div>
            <div className="progress-container">
                <div className="progress-title">
                    <span>Story name</span>
                </div>
                <div className="timeline">
                    <div className="playhead"></div>
                </div>
            <div className="progress-time">
                <span className="progress-time-played">4:55 </span>
                <span className="progress-time-total">/ 8:15</span>
            </div>
            </div>

        </div>

         </div>
    )
}
}

When I console log the refs it always returns the same 4 stories. How can I access the ref of the element I'm clicking on? I need to do it so I can render the story name on the progress bar.

Dan Cristian
  • 13
  • 1
  • 4
  • Its returning the same 4 because you are assigning all 4 the same ref value. I would give it a ref of something like `this.myRef + '_' + k`. Then you can `console.log(this[myRef + '_0']).current` or something similar – TPHughes May 12 '18 at 14:33

1 Answers1

1

No need for refs here - instead, just pass back the entire story to your onClick callback:

// instead of this
onClick={() => this.playAudio(story.playing_url)}
// do this
onClick={() => this.playStory(story)}

Then, you can setState inside of playStory so that this.state.story is the currently playing story.

playStory(story) {
  this.setState({ story: story });
  this.playAudio(story.playing_url);
}

And in your render method, you just look at this.state.story:

var story_title = null;
if (this.state && this.state.story) {
  story_title = <span className="story-title">{this.state.story}</span>;
}

return (
  <!-- ... snip ... -->
  <div className="progress-title">
    {story_title}
  </div>
);
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • The problem with this syntax `onClick={() => this.playAudio(story.playing_url)}` is that a different callback is created each time the button renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components as you are actually passing, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem. – Ankur Soni May 12 '18 at 14:44
  • 1
    This is correct - at that point you can replace the closure with a separate component (e. g. ``) – Sean Vieira May 13 '18 at 13:53