【问题标题】:How to make all the collapsible item open by default in react?如何在反应中默认打开所有可折叠项目?
【发布时间】:2020-07-21 14:41:38
【问题描述】:

我使用 reactstrap 制作了一个带有令牌的可折叠按钮,并且按钮点击折叠一切正常。

我希望这个场景保持原样,但另一方面,我如何修改它以使所有可折叠按钮在页面初始呈现时打开。

访问页面时,所有标记都需要可见,这意味着所有可折叠项目都需要打开。

如果我们给予,

this.state = {
      open: [0 , 1, 2]
    };

然后它将被打开,但对于这篇文章它会起作用,而在实际应用中我不知道确切的索引是什么,所以像这样的硬编码是行不通的。

请帮助我打开所有n 数量的可折叠数据,以在初始状态下打开,点击按钮后,它应该就像现在一样(打开/关闭)令牌。

const data = [{"orderId":1,"orderNo":"123", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3"]}] },
{"orderId":2,"orderNo":"456", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1","Token3"]}] },
{"orderId":3,"orderNo":"789", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3", "Token4"]}] }
]

const {Component, Fragment} = React;
const {Button, Collapse} = Reactstrap;

class Menu extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: []
    };
  }
  
  toggle = idx => () => {
    this.setState(prevState => ({open: this.state.open.includes(idx) ? prevState.open.filter(x => x !== idx) : [...prevState.open, idx]})
  )}
  render() {
  const { open } = this.state;
    return <div> 
      {
        data.map((levelOneItem, i) => {
          return(
          <div>
          <div> Order Id:  {levelOneItem.orderId} </div>
          {
            levelOneItem.orderParts.map((levelTwoItem, j) => {
               return(
                  <div>
                  <div> Order Part Id: {levelTwoItem.orderPartsId} </div>
                  <Button onClick={this.toggle(i)}>Display Token</Button>
                  <Collapse isOpen={open.includes(i)}>
                    {
                       <div>
                        {levelTwoItem.regTokens.map((levelThreeItem, k) => {
                          return(<span> {levelThreeItem} </span>)
                        })
                     }
                       </div>
                    }
                  </Collapse>
                  </div>
               )
            })
          }
          </div>
          )
        })
      }
    </div>;
  }

}


ReactDOM.render(<Menu />, document.getElementById("root"));
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>

<div id="root"></div>

【问题讨论】:

    标签: javascript reactjs accordion reactstrap


    【解决方案1】:

    如果您希望在初始化时将它们全部打开。

    表示所有项目的索引列表

    可以根据数据长度生成[0, 1, 2...]这样的列表

    this.state = {
      open: [...Array(data.length).keys()]
    }
    

    const data = [{"orderId":1,"orderNo":"123", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3"]}] },
    {"orderId":2,"orderNo":"456", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1","Token3"]}] },
    {"orderId":3,"orderNo":"789", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3", "Token4"]}] }
    ]
    
    const {Component, Fragment} = React;
    const {Button, Collapse} = Reactstrap;
    
    class Menu extends Component {
      constructor(props) {
        super(props);
        this.state = {
          open: [...Array(data.length).keys()]
        };
      }
      
      toggle = idx => () => {
        this.setState(prevState => ({open: this.state.open.includes(idx) ? prevState.open.filter(x => x !== idx) : [...prevState.open, idx]})
      )}
      render() {
      const { open } = this.state;
        return <div> 
          {
            data.map((levelOneItem, i) => {
              return(
              <div>
              <div> Order Id:  {levelOneItem.orderId} </div>
              {
                levelOneItem.orderParts.map((levelTwoItem, j) => {
                   return(
                      <div>
                      <div> Order Part Id: {levelTwoItem.orderPartsId} </div>
                      <Button onClick={this.toggle(i)}>Display Token</Button>
                      <Collapse isOpen={open.includes(i)}>
                        {
                           <div>
                            {levelTwoItem.regTokens.map((levelThreeItem, k) => {
                              return(<span> {levelThreeItem} </span>)
                            })
                         }
                           </div>
                        }
                      </Collapse>
                      </div>
                   )
                })
              }
              </div>
              )
            })
          }
        </div>;
      }
    
    }
    
    
    ReactDOM.render(<Menu />, document.getElementById("root"));
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>
    
    <div id="root"></div>

    【讨论】:

    【解决方案2】:

    看起来 reactstrap 不支持这些东西。但这里有一个解决方法。

    const data = [{"orderId":1,"orderNo":"123", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3"]}] },
    {"orderId":2,"orderNo":"456", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1","Token3"]}] },
    {"orderId":3,"orderNo":"789", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3", "Token4"]}] }
    ]
    
    const {Component, Fragment} = React;
    const {Button, Collapse} = Reactstrap;
    
    class Menu extends Component {
      constructor(props) {
        super(props);
        this.state = {
          open: [],
          isFirstTime:true
        };
      }
      
      toggle = idx => () => {
      if(this.state.isFirstTime){
      var ids=data.map(item=>item.orderId);
      
      //get all id of data here as ids;
     
      this.setState({
        isFirstTime:false,
        open:ids.filter(x=>x!==idx)
      });
      }else{
        this.setState(prevState => ({open: this.state.open.includes(idx) ? prevState.open.filter(x => x !== idx) : [...prevState.open, idx]})
      )
      }
      }
      render() {
      const { open } = this.state;
        return <div> 
          {
            data.map((levelOneItem, i) => {
              return(
              <div>
              <div> Order Id:  {levelOneItem.orderId} </div>
              {
                levelOneItem.orderParts.map((levelTwoItem, j) => {
                   return(
                      <div>
                      <div> Order Part Id: {levelTwoItem.orderPartsId} </div>
                      <Button onClick={this.toggle(levelOneItem.orderId)}>Display Token</Button>
                      <Collapse isOpen={open.includes(levelOneItem.orderId)||this.state.isFirstTime}>
                        {
                           <div>
                            {levelTwoItem.regTokens.map((levelThreeItem, k) => {
                              return(<span> {levelThreeItem} </span>)
                            })
                         }
                           </div>
                        }
                      </Collapse>
                      </div>
                   )
                })
              }
              </div>
              )
            })
          }
        </div>;
      }
    
    }
    
    
    ReactDOM.render(<Menu />, document.getElementById("root"));
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>
    
    <div id="root"></div>

    这里isFirstTime表示初始状态,所以所有collapse都为true,当其中任何一个发生变化时,isFirstTime为false,其余按原样进行

    【讨论】:

    • 您的 sn-p 不起作用并且有错误。您能解决这个问题吗??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2012-09-23
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多