Search code examples
reactjschildren

Reusable component data render using switch case


I have a reusable component that mimics a button function. I need to display four different types of content based on FAQ value, from my reusable child component 'CustomButton' back to parent component.

CustomButton.js

const CustomButton = (props) => {
    const handleClick = () => {
        switch(props.faq){
            case 'general':
                return 'div 1';
            case 'payment':
                return 'div 2';
            case 'business':
                return 'div 3';
            case 'online':
                return 'div 4';
        }
    }
        return (
                <div>
                    {React.cloneElement(props.children, {onClick: handleClick})}
                </div>
        )
}

export default CustomButton

Faq.js

export default class Faq extends Component {
    render() {
        return (
            <div className="set_faq">
                <div style={{display: 'flex', flexDirection:'row', justifyContent: 'space-around'}}>
                    <CustomButton faq={'general'}><button>General FAQ</button></CustomButton>
                    <CustomButton faq={'payment'}><button>Payment FAQs</button></CustomButton>
                    <CustomButton faq={'business'}><button>Business FAQs</button></CustomButton>
                    <CustomButton faq={'online'}><button>Online Sellers</button></CustomButton>
                </div>
                <div>
                    {/* to display content here based on div clicked */}
                </div>

            </div>
        )
    }
}

I am unable to handle the result returned by switch statement back to the CustomButton file to render the data. Kindly help to complete the work around.


Solution

  • To achieve what you want, you need to lift the state up and manage the value clicked direclty inside the Faq component instead of CustomButton. This way, you can manage a unique state and display what you need to display accordingly.

    The CustomButton is simplified:

    const CustomButton = props => {
      return <div onClick={props.handleClick}>{props.children}</div>;
    };
    

    And App component now manages a state and the handleClick function which now saves the faq clicked in a state. This way you can render the data based on what was clicked

    class App extends React.Component {
      state = { clickedValue: "" };
    
      handleClick = faq => ev => {
        switch (faq) {
          case "general":
            this.setState({ clickedValue: "div 1" });
            break;
          case "payment":
            this.setState({ clickedValue: "div 2" });
            break;
          case "business":
            this.setState({ clickedValue: "div 3" });
            break;
          case "online":
            this.setState({ clickedValue: "div 4" });
            break;
          default:
            return;
        }
      };
      render() {
        return (
          <div className="set_faq">
            <div
              style={{
                display: "flex",
                flexDirection: "row",
                justifyContent: "space-around"
              }}
            >
              <CustomButton handleClick={this.handleClick("general")}>
                <button>General FAQ</button>
              </CustomButton>
              <CustomButton handleClick={this.handleClick("payment")}>
                <button>Payment FAQs</button>
              </CustomButton>
              <CustomButton handleClick={this.handleClick("business")}>
                <button>Business FAQs</button>
              </CustomButton>
              <CustomButton handleClick={this.handleClick("online")}>
                <button>Online Sellers</button>
              </CustomButton>
            </div>
            <div>{this.state.clickedValue}</div>
          </div>
        );
      }
    }
    

    Working example here: https://codesandbox.io/s/angry-yalow-bvgbe

    PS: I tried to limit modifications on your code to resolve your issue however, it's not the best HTML markup to have a button inside a div which captures the onClick event.