1

I have a list of items, if an item is clicked it shall show its content. Do I need for each list item a boolean in the state object or can I do it with add and remove classname like in jquery?

Code:

 <ul>
  <li> item <div className="hidden"> some extra text ... </div> </li>
  <li> item <div className="hidden"> some extra text ... </div> </li>
  <li> item <div className="hidden"> some extra text ... </div> </li>
  <li> item <div className="hidden"> some extra text ... </div> </li>
</ul>

3 Answers 3

3

Do I need for each list item a boolean in the state object?

Yes, you need to maintain a boolean for each list item in state variable, and on the basis of that state value, render the content of list items, Try this:

this.state = {showItems: []}

onClick(index){
     console.log(index);
     let showItems = this.state.showItems.slice();
     showItems[index] = !showItems[index];
     this.setState({showItems});
}

<ul>
  <li onClick={this.onClick.bind(this,0)}> item {this.state.showItems[0] ? <div> some extra text ... </div> : null} </li>
  <li onClick={this.onClick.bind(this,1)}> item {this.state.showItems[1] ? <div> some extra text ... </div> : null}</li>
  <li onClick={this.onClick.bind(this,2)}> item{this.state.showItems[2] ? <div> some extra text ... </div> : null} </li>
  <li onClick={this.onClick.bind(this,3)}> item {this.state.showItems[3] ? <div> some extra text ... </div> : null}</li>
</ul>

Check this working Snippet:

class App extends React.Component {
  constructor(){
    super();
    this.state = {showItems:[]}
  }
      
  onClick(index){
    let showItems = this.state.showItems.slice(0);
    showItems[index] = !showItems[index];
    this.setState({showItems});
  }
    
  render() {
    return (
      <div className="App">
        <ul>
          <li onClick={this.onClick.bind(this,0)}> item {this.state.showItems[0] ? <div> some extra text ... </div> : null} </li>
          <li onClick={this.onClick.bind(this,1)}> item {this.state.showItems[1] ? <div> some extra text ... </div> : null}</li>
          <li onClick={this.onClick.bind(this,2)}> item{this.state.showItems[2] ? <div> some extra text ... </div> : null} </li>
          <li onClick={this.onClick.bind(this,3)}> item {this.state.showItems[3] ? <div> some extra text ... </div> : null}</li>
        </ul>
        <div style={{marginTop: 100}}>*click on item to open submenu</div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));
li{
   cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='container'/>

Check fiddle for working example: https://jsfiddle.net/mayankshukla5031/18hheyx1/

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

Comments

2

I think you should use react-bootstrap. else you can use state and update it manually.

const accordionInstance = (
  <Accordion>
    <Panel header="Collapsible Group Item #1" eventKey="1">
      test
    </Panel>
    <Panel header="Collapsible Group Item #2" eventKey="2">
     test 1
    </Panel>
    <Panel header="Collapsible Group Item #3" eventKey="3">
      test 2
    </Panel>
  </Accordion>
);

ReactDOM.render(accordionInstance, mountNode);

Document : https://react-bootstrap.github.io/components.html#panels-accordion

Comments

1

Here is a very simple to use library, which lets you define conditions on classnames. Library is also called classnames

For instance:

import classNames from 'classnames'


<li> item 
    <div className={ classNames({
       'some-static-classname' : true,
       'hidden'                : this.state.hiddenItems.includes('itemX')
     }) }
    > 
        some extra text ... 
    </div> 
</li>

So this library is only useful to reduce the boilerplate on your conditions. What you need is also keeping the data of hidden/shown items. You might keep this kind of state in react internal state. Then just put your conditions.

Here is another similar question and answer I answered. Hope it helps.

Comments

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.