0

I am trying to map my state which contains several words to a react-bootstrap dropdown menu below I have included my attempt

my state looks like "some words to view" with each word separated by a space

I have tried mapping the items into a 'ul' element using a for loop but The dropdown doesn't show anything at all.


import React, { Component } from 'react';
import '../App.css';
import {Button,InputGroup,Dropdown,DropdownButton,ButtonGroup} from 'react-bootstrap';

export default class BreakPointsDropdown extends Component{

  constructor(props){
    super(props);

  }

  render(props){
    return (
    <Dropdown as={ButtonGroup}>
    <Button variant="outline-dark"onClick={this.props.addBreakPointMode}>Add Breakpoint</Button>

    <Dropdown.Toggle split variant="outline-dark" id="dropdown-split-basic" />

    <Dropdown.Menu id="menulist" onClick={()=>{
      var list = this.props.listOfBreakPoints.split(" ")
      var ul = document.createElement("ul")

        for(let i = 0; i< list.length; i++){
          let li = document.createElement("li")
          li.innerHTML= list[i]
          ul.append(li)
        }
        document.getElementById("menulist").append(ul)
    }}>

    </Dropdown.Menu>
  </Dropdown>

    );
  }

};

I would like the dropdown menu to contain a list of words from my state which I can select onclick

3
  • What is the dropdown component from? You most likely shouldn't be manually manipulating DOM. Commented Oct 16, 2019 at 2:46
  • I'm sorry I'm not sure exactly how to answer. I am rendering the dropdown menu as its own component I will update the code to show this. Commented Oct 16, 2019 at 3:27
  • I think by your statement you mean: use a prop as the content instead of generating it onClick? Commented Oct 16, 2019 at 14:55

1 Answer 1

3

You should avoid modifying the dom directly...unless it's really required. Your component can be easily rewritten as

import React, { Component } from 'react';
import {render} from "react-dom";
import {Button,Dropdown,ButtonGroup} from 'react-bootstrap';

export default class BreakPointsDropdown extends Component{
  handleSelect = (value) => {
    alert(value);
    // Do something with the value
  }

  render(){
    return (
    <Dropdown as={ButtonGroup}>
    <Button variant="outline-dark"onClick={this.props.addBreakPointMode}>Add Breakpoint</Button>

    <Dropdown.Toggle split variant="outline-dark" id="dropdown-split-basic" />

    <Dropdown.Menu id="menulist">
        {this.props.listOfBreakPoints.split(" ").map(eachBreakpoint => {
            return (
              <Dropdown.Item
                onClick={() => this.handleSelect(eachBreakpoint)}
                key={eachBreakpoint}
              >
                {eachBreakpoint}
              </Dropdown.Item>
            );
        })}
    </Dropdown.Menu>
  </Dropdown>

);
  }
};

And rendered with

<BreakPointsDropdown listOfBreakPoints="Hi Hello How are you"/>

A sample playground: https://stackblitz.com/edit/react-msdpvz

Coming back to the question..

*"I have tried mapping the items into a 'ul' element using a for loop but The dropdown doesn't show anything at all."*

Because your entire code is inside an onclick handler. Your code runs when you click on the empty dropdown section that you get on clicking the dropdown arrow.

<Dropdown.Menu id="menulist" onClick={()=>{
      var list = this.props.listOfBreakPoints.split(" ")
      var ul = document.createElement("ul")

        for(let i = 0; i< list.length; i++){
          let li = document.createElement("li")
          li.innerHTML= list[i]
          ul.append(li)
        }
        document.getElementById("menulist").append(ul)
    }}> 

Try it here: https://stackblitz.com/edit/react-ruat5w

Click on dropdown arrow -> You should see an empty div -> Click on the empty div to see your dom modification code getting executed.

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

1 Comment

thanks for the description and very verbose explanation! this solution worked for me.

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.