Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap select element not rendered with react-router

I am making a basic app in reactjs. I've setup routes for 3 components. The problem is select fields don't appear when the component is rendered. I'm using bootstrap-select library for the select fields.

The select fields that have className as "selectpicker" do not render, they just aren't there. They showed up when I removed "selectpicker" from the className. When using "selectpicker", they show up when the browser page is reloaded.

Below is a snippet from my code: https://codesandbox.io/s/determined-panini-2mmv3 All three components are almost similar.

import React from 'react'
import A from "./A"
import B from "./B"
import C from "./C"
import {BrowserRouter as Router, Switch, Link, Route} from "react-router-dom"

class App extends React.Component{
  constructor(){
    super()
  }
    render(){
      return(
        <div>
          <Router>
            <ul>
              <li><Link to="/">TO A</Link></li>
              <li><Link to="/page1">TO B</Link></li>
              <li><Link to="/page2">TO C</Link></li>
            </ul> 
            <Switch>
              <Route exact path='/' component={A}/>
              <Route path='/page1' component={B}/>   {/* components B and C have select field with selectpicker class*/}
              <Route path="/page2" component={C}/>
            </Switch>
          </Router>
        </div>
      )
    }
}

export default App
{/*Component A*/}

import React from "react"

class A extends React.component{
  constructor(){
    super()
    this.state={
      componentA: ""
    }
    this.handleChange = this.handleChange.bind(this)
  }

  handleChange(event){
    const {name, value, type, checked} = event.target
    type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value })
  }

  render(){
    return(
      <div className="form-group row">
        <label htmlFor="tempid" className="col-sm-2 col-form-label">Choose an option</label>
        <div className="col-sm-10">
            <select 
              className="form-control custom-select selectpicker"
              name = "componentA" 
              id = "tempid"
              value = {this.state.componentA}
              onChange = {this.handleChange} 
              required
            >
              <option value="" style={{display:"none"}} disabled selected>Choose one</option>
              <option value="p">P</option>
              <option value="q">Q</option>
              <option value="r">R</option>
              <option value="s">S</option> 
            </select>
        </div>
      </div>
    )
  }
}
export default A

Following is my index.html file, and i have included the bootstrap and bootstrap-select correctly. Its working fine when rendering the components individually. The problem arose when I started with routing.

<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="theme-color" content="#000000">
  <meta name="description" content="Web site created using create-react-app">

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.10/css/bootstrap-select.min.css">


  <title>React App</title>

</head>
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>

  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.10/js/bootstrap-select.min.js" type="text/javascript"></script>

</body></html>

Here's the link to my problem's codesandbox https://codesandbox.io/s/determined-panini-2mmv3

Actual output: The select input fields with "selectpicker" class don't show up at all. Only the labels and other text inputs are visible. When the "selectpicker" className is removed, it works as expected. I get the following as output: My output

Expected: The select input field to be rendered. The expected should be as follows: enter image description here

like image 701
Abhinandan Madaan Avatar asked Sep 26 '19 12:09

Abhinandan Madaan


1 Answers

I tried, as suggested by one of the comments on the question, to add $('select').selectpicker() in my componentDidMount(). But it did not work as expected. Instead I excountered an error __WEBPACK_IMPORTED_MODULE_8_jquery___default(…)(…).selectpicker is not a function. After struggling for days literally, I was able to fix the issue using the answer from React Error : __WEBPACK_IMPORTED_MODULE_4_jquery___default(...)(...).modal is not a function.

The import import $ from 'jquery' creates a local variable named $ inside your module, which then gets used by $('.selectpicker').selectpicker() (instead of the global $ you wanted).

The quickest fix would be to explicitly use the jQuery $ from the global context (which has been extended with your $.selectpicker() because you referenced that in your script tag.

window.$('.selectpicker').selectpicker()

like image 91
Abhinandan Madaan Avatar answered Oct 19 '22 23:10

Abhinandan Madaan