简体   繁体   中英

Converting react class component to functional component, rendering perfectly but functionality lost?

I am making a small audio player application and attempting to convert my react class component into a functional component.

The original code for the class component is here:

class Player extends React.Component {

    constructor(){
    super()

    this.state = {
        tracks: [
          {title: "first track", data: track1},
          {title: "second track", data: track2},
          {title: "third track", data: track3},
        ],
        currentTrack: 0,
    }

    }

     changeData(trackIndex){
      this.setState({currentTrack: trackIndex})
    }
  
    render(){
        return <div style={{color: this.props.color}}>
            <h1>Player</h1>
           <AudioPlayer
            src= {this.state.tracks[this.state.currentTrack].data}
            />
            <div style={{color: "green"}}>
                <ul>
                    {this.state.tracks.map((trackElem, index) => (
                       <li onClick={()=> this.changeData(index)}>{trackElem.title}</li>
                    ))}
                </ul>
            </div>
        </div>
    }
}

I have attempted the conversion below:

const Player2 = () => {

   const Items = [
          {title: "first track", data: track1},
          {title: "second track", data: track2},
          {title: "third track", data: track3},
    ]; 

    const [activeTrack, setActiveTrack] = useState(0);

    function ChangeData(trackIndex) {
        setActiveTrack({activeTrack : trackIndex});
    }

    return (
        <div >
           <h1>Player</h1>
           <AudioPlayer
            src= {activeTrack.data}
            />
            <div >
                <ul>
                    {Items.map((trackElem, index) => (
                       <li onClick={()=> ChangeData(index)}>{trackElem.title}</li>
                    ))}
                </ul>
            </div>
        </div>
    )
}

Aside from removing some of the props that are associated with styling the logic is basically the same. The only difference is the handling of the current track, I have attempted to represent this by using states.

When rendering the object to a different page it appears to the screen completely fine, the only issue is that the tracks themselves no longer trigger a response in the audio player.

Would really appreciate it if someone could identify anything I've missed in making the conversion?

Here:

const [activeTrack, setActiveTrack] = useState(0);

So activeTrack is a number in state initially. But then you do

src= {activeTrack.data}

which doesn't make sense - the number doesn't have a data property. Another problem is

setActiveTrack({activeTrack : trackIndex});

Now you're setting the active track to an object with an activeTrack property, which is different from the above two formats as well.

Pick one way to represent, set, and retrieve state throughout the component, such as the index:

function ChangeData(trackIndex) {
    setActiveTrack(trackIndex);
}
<AudioPlayer
    src={Items[activeTrack].data}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM