Neo Genesis
Neo Genesis

Reputation: 990

React: Trigger button click from array map by another child

I have a parent component App and it has a child Content & Trigger. From the Content component, I have an array of content with radio button and a hidden button. The Trigger component has only one button. 🤔

My question is, how can I trigger a button click inside the Content component from the Trigger component depending on what the user selected on the Content component. 🤯

If my explanation is hard to understand, maybe my code does. Thank you. 🙏

CodeSandbox Sample
https://codesandbox.io/s/laughing-kirch-g2r10?fontsize=14&hidenavigation=1&theme=dark

App.js

import React from "react";
import Content from "./Content";
import Trigger from "./Trigger";
import "./styles.css";

class App extends React.PureComponent {
  state = {
    selectedOption: ""
  };

  onRadioButtonChange = name => {
    this.setState({
      selectedOption: name
    });
  };

  onClickTriggerButton = e => {
    const { selectedOption } = this.state;
    e.preventDefault();
    switch (selectedOption) {
      case "opt1":
        console.log("trigger click on option 1");
        break;
      case "opt2":
        console.log("trigger click on option 2");
        break;
      case "opt3":
        console.log("trigger click on option 3");
        break;
      default:
        console.log("Select a method...");
    }
  };

  render() {
    return (
      <div className="App">
        <Content onRadioButtonChange={this.onRadioButtonChange} />
        <Trigger onClickTriggerButton={this.onClickTriggerButton} />
      </div>
    );
  }
}

export default App;

Content.js

import React from "react";

class Content extends React.PureComponent {
  render() {
    const { onRadioButtonChange } = this.props;

    const tabs = [
      {
        name: "option_1_name",
        content: (
          <div className="Option-Method">
            <input
              type="radio"
              name="group"
              onChange={() => onRadioButtonChange("opt1")}
            />
            Option Medthod 1 - Randon text...
            <button
              hidden
              onClick={() => console.log("option 1 button clicked!")}
            />
          </div>
        )
      },
      {
        name: "option_2_name",
        content: (
          <div className="Option-Method">
            <input
              type="radio"
              name="group"
              onChange={() => onRadioButtonChange("opt2")}
            />
            Option Medthod 2 - Randon text...
            <button
              hidden
              onClick={() => console.log("option 2 button clicked!")}
            />
          </div>
        )
      },
      {
        name: "option_3_name",
        content: (
          <div className="Option-Method">
            <input
              type="radio"
              name="group"
              onChange={() => onRadioButtonChange("opt3")}
            />
            Option Medthod 3 - Randon text...
            <button
              hidden
              onClick={() => console.log("option 3 button clicked!")}
            />
          </div>
        )
      }
    ];

    return (
      <form className="Content">
        <fieldset id="group">
          {tabs.map((attribute, index) => {
            const key = `${attribute.name}-${index}`;
            return (
              <div key={key} className="Option">
                {attribute.content}
              </div>
            );
          })}
        </fieldset>
      </form>
    );
  }
}

export default Content;

Trigger.js

import React from "react";

class Trigger extends React.PureComponent {
  render() {
    const { onClickTriggerButton } = this.props;

    return (
      <div className="Trigger">
        <button onClick={onClickTriggerButton}>Trigger Selected Option</button>
      </div>
    );
  }
}

export default Trigger;

Upvotes: 0

Views: 815

Answers (1)

Vivek
Vivek

Reputation: 505

Pass ref to the Content component and for each hidden button check for the selectedOption if that matches set ref for that hidden button. Also wrap the Content component in React.forwardRef.

<button
   hidden
   ref={"opt1" === selectedOption ? ref : null}
   onClick={() => console.log("option 1 button clicked!")}
/>

https://codesandbox.io/s/strange-hodgkin-jm84w?file=/src/Content.js:507-671

Upvotes: 1

Related Questions