skip to Main Content

I’m using ReactJS, and shopify’s polaris in order to create a website. I’m very new to react so this might be a newbie question but I looked over the internet and couldn’t manage to put the pieces together.

I have a dropdown list and basically whenever the user clicks on an item from a list I want to add a button next to the dropdown. Here is my code:

import React from "react";
import { ActionList, Button, List, Popover } from "@shopify/polaris";

export default class ActionListExample extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      active: false,
      title: "Set Period",
    };
  }

renderButton() {
    console.log("Button clicked")
    return (
      <div>
        <Button fullWidth={true}>Add product</Button>;
      </div>
    );
 }

togglePopover = () => {
this.setState(({ active }) => {
  return { active: !active };
});
};

render() {
  const activator = (
    <Button onClick={this.togglePopover}>{this.state.title}</Button>
  );
return (
  <div style={{ height: "250px" }}>
    <Popover
      active={this.state.active}
      activator={activator}
      onClose={this.togglePopover}
    >
      <ActionList
        items={[
          {
            content: "One",
            onAction: () => {
              this.setState({ title: "One" }, function() {
                this.togglePopover();
                this.renderButton() //THIS IS WHERE I CALL THE METHOD
              });
            }
          }
        ]}
      />
    </Popover>
  </div>
);
}
}

I’ve placed a comment in the code to show where I call the renderButton() method. Whenever I click the “One” element in the dropdown, it prints out “Button clicked” but nothing gets rendered to the screen. Any help is greatly appreciated. Thanks in advance!

3

Answers


  1. Chosen as BEST ANSWER

    Thanks to everyone's help I finally was able to do this. I placed an extra attribute in the state called isButton and I initially set it equal to false. Here is my render function:

    render() {
     const activator = (
       <Button onClick={this.togglePopover}>{this.state.title}</Button>
     );
    return (
      <div style={{ height: "250px" }}>
        <Popover
          active={this.state.active}
          activator={activator}
          onClose={this.togglePopover}
        >
          <ActionList
            items={[
            {
            content: "One",
            onAction: () => {
              this.setState({ title: "One", isButton: true }, function() { //Set isButton to true
                this.togglePopover();
              });
            }
          }
        ]}
      />
    {this.state.isButton && this.renderButton()} //ADDED HERE
    </Popover>
      </div>
    );
    }
    

    Please look at the comments to see where code was changed. Thanks!


  2. You need to add another variable to check if an item is clicked, and as @azium commented, you need to add the output to your JSX, not inside the onAction function.

    As of right now, you close the Popper when an item is clicked, setting this.state.active to false, so you can’t rely on that to render your button. You need to add something like this.state.isButton or something and in onAction include:

    onAction: () => {
      this.setState({ title: "One", isButton: true }, () => {
        this.togglePopover();
       });
    }
    

    and then in your JSX:

    {this.state.isButton && this.renderButton()}
    
    Login or Signup to reply.
  3. This is a perfect use case for conditional rendering.
    You basically want to render a component based on a condition (Boolean from your state in this case).

    Conditional rendering can be written is several ways as you can see in the docs.

    In your case i would go for something like this:

    return (
      <div style={{ height: "250px" }}>
        <Popover
          active={this.state.active}
          activator={activator}
          onClose={this.togglePopover}
        >
          <ActionList
            items={[
              {
                content: "One",
                onAction: () => {
                  this.setState({ title: "One" }, function() {
                    this.togglePopover();
                  });
                }
              }
            ]}
          />
          {this.state.active && this.renderButton()}
        </Popover>
      </div>
    );
    }
    }
    

    Note that i just placed it at a random place, feel free to move it wherever you need it in the markup.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search