0

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;

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a way by using state, ref, or by passing a handler instead of checking it from a DOM? 🤔
One doubt, why there is a hidden button for each radio button. If they are used to submit a form, you can handle that using single button for form and ref can be passed to that button from parent and click can be triggered for that ref.
Actually every option method has its own forms and submits handler and as per the designer's design, there should only one button to trigger the submit button depending on what option method the user selected. 😞
Hi Neo Genesis, I have made changes using ref, but Iam not sure whether this is a perfect fix. Check whether your are ok with this fix. codesandbox.io/s/strange-hodgkin-jm84w?file=/src/App.js
Thank you brother this works for me! Thanks for forwardedRef. Can you please update your answer so I can mark it. 👍

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.