Search code examples
reactjscomponentsstateonchange

(React) Render a component depending on state after already returning some content


I made a dropdown menu with different codecs that the user can choose and then depending on the codec that the user selected, I want to render another component which gives the user options related to that codec. For example, if the user selects MP3, I want to show my <MP3Options/> component. The issue is that I don't know how to render the <MP3Options/> component in addition to the codecs dropdown menu. What I have currently makes the the <MP3Options/> component show as it should when MP3 is selected, but the codecs dropdown menu no longer shows. This is not good because if the user decides to choose another codec instead, they can't as the dropdown menu no longer shows.

I believe this is because I'm returning <MP3Options/> and therefore the rest of the code (for showing the dropdown menu) doesn't execute. What I want keep showing the dropdown menu AND also show the appropriate component for the codec selected (for example <MP3Options/> if MP3 is selected).

Here's my code (I can't put the if (this.state.value === 'MP3') line after the dropdown menu div because then this.state.value doesn't work or something):

import React from 'react'
import MP3Options from './MP3'

class CodecSelector extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "AAC"};
  }
  onCodecChange = (event) => {
    this.setState({value: event.target.value})
  }

  render() {
    if (this.state.value === 'MP3') {
      return <MP3Options/>
    }
    return (
      <div>
        <select id="codecs" onChange={this.onCodecChange} value={this.state.value}>
          <option value="AAC">AAC (.m4a)</option>
          <option value="AC3">AC3 (Dolby Digital)</option>
          <option value="ALAC">ALAC</option>
          <option value="CAF">CAF (.caf)</option>
          <option value="DTS">DTS</option>
          <option value="FLAC">FLAC</option>
          <option value="MKA">MKA (extract audio without encoding it)</option>
          <option value="MKV">MKV (.mkv)</option>
          <option value="MP3">MP3</option>
          <option value="MP4">MP4 (.mp4)</option>
          <option value="Opus">Opus (.opus)</option>
          <option value="Vorbis">Vorbis (.ogg)</option>
          <option value="WAV">WAV</option>
        </select>
      </div>
    );
  }
}

export default CodecSelector;```

Solution

  • I believe what you are looking for is to conditionally render your components,

    import React from 'react'
    import MP3Options from './MP3'
    
    class CodecSelector extends React.Component {
    
      constructor(props) {
        super(props);
        this.state = { value: "AAC" };
      }
    
      onCodecChange = (event) => {
        this.setState({ value: event.target.value })
      }
    
      renderComponent = () => {
        const { value } = this.state;
        switch (value) {
          case 'AAC':
            return <AACOptions />;
          case 'MP3':
            return <MP3Options />;
          default:
            return null;
        }
      }
    
      render() {
        return (
          <div>
            <select id="codecs" onChange={this.onCodecChange} value={this.state.value}>
              <option value="AAC">AAC (.m4a)</option>
              <option value="AC3">AC3 (Dolby Digital)</option>
              <option value="ALAC">ALAC</option>
              <option value="CAF">CAF (.caf)</option>
              <option value="DTS">DTS</option>
              <option value="FLAC">FLAC</option>
              <option value="MKA">MKA (extract audio without encoding it)</option>
              <option value="MKV">MKV (.mkv)</option>
              <option value="MP3">MP3</option>
              <option value="MP4">MP4 (.mp4)</option>
              <option value="Opus">Opus (.opus)</option>
              <option value="Vorbis">Vorbis (.ogg)</option>
              <option value="WAV">WAV</option>
            </select>
            {this.renderComponent()}
          </div>
        );
      }
    }
    
    export default CodecSelector;