Как сделать так, чтобы все складные элементы открывались по умолчанию в реакции? - PullRequest
1 голос
/ 09 апреля 2020

Я сделал разборную кнопку с токенами внутри, используя реактивную ленту, и все работает нормально для свертывания нажатия кнопки.

Я бы хотел, чтобы этот сценарий был таким, как есть, но с другой стороны, как я могу изменить это позволяет открыть все разборные кнопки при первоначальном рендеринге страницы.

При посещении страницы все токены должны быть видны, что означает, что все разборные элементы должны быть открыты.

Если мы дайте,

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>

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Похоже, что ремешок не поддерживает такие вещи. Но вот обходной путь к этому.

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 указывает начальное состояние, поэтому все коллапс станет истинным, когда любой из них изменится, isFirstTime будет ложным, а остальные будут выполнены как есть

0 голосов
/ 09 апреля 2020

Если вы хотите, чтобы все они были открыты при инициализации.

Это означает, что индексный список всех элементов

Вы можете создать список типа [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>
...