簡體   English   中英

在React JSX中有條件地渲染組件部分

[英]Conditionally rendering component sections in React JSX

根據MDN的說法,“您還可以針對每種情況執行多個操作,並以逗號分隔。” 下面的示例起作用:

var stop = false, age = 23;

age > 18 ? (
    alert("1"),
    alert("2")
) : (
    stop = true,
    alert("Sorry, you are much too young!")
);

但是我似乎無法在React中做如下所示的事情。 我希望同時顯示“是”和“否”按鈕,但是它只顯示“否”按鈕。

return (
  <div className="topcoat-list">
    <ul className="topcoat-list__container">
    {
      notes.map(function (note) {
        var title = note.content.substring(0, note.content.indexOf("\n"));
title = title || note.content;
        var toggleDeleteDialogs = this.state.isConfirming && note.id === notepad.selectedId;
        var disableDelete = this.state.isConfirming && note.id !== notepad.selectedId;

          return (
          <li key={note.id} onClick={this.onSelectNote.bind(null, note.id)} className="topcoat-list__item">
            {title}

            {
              toggleDeleteDialogs ?
              (
                <button key={note.id} onClick={this.deleteThisNote.bind(null, note.id)} className="half">Yes</button>,
                <button className="half" onClick={this.onCancelDelete}>No</button>
              ) : (
              <button key={note.id} onClick={this.deleteThisNote.bind(null, note.id)} className="full" disabled={disableDelete ? "disabled" : ""}>Delete Note</button>
              )
            }

          </li>

        );
      }.bind(this))
    }
    </ul>
  </div>
);

完整標記: https//jsfiddle.net/55fvpcLo/

我的語法是否正確,還是可以更優雅地完成?

小提琴似乎沒有用,但是我可以重現這種行為。 盡管它不會引起Adjacent JSX elements must be wrapped in an enclosing tag錯誤中,但我懷疑這可能是它不起作用的原因,因為相鄰元素實際上是您要嘗試執行的操作。

我認為最簡單的解決方案是將兩個元素包裝在一個封閉的標簽中而不是括號中。

您還可以返回一個JSX組件數組,例如

{ 
  toggleDeleteDialogs ?
  [<Button ... />, <Button ... />] :
  <Button .../> 
}

@Adam Stone正確的是,問題在於有相鄰的JSX元素未包裝在結束標記中。

就是說,您要求使用最優雅的方法來解決問題。

我對您的代碼進行了以下更改:

  • 使用此函數有選擇地隱藏JSX元素:

     var hideIfFalse=function(boolean){ return boolean? {} : {display : 'none'}; }; 

    您可以這樣使用:

     <div style={hideIfFalse(toggleDeleteDialogs)} /> 
  • 將呈現列表項的邏輯分離為renderChildren方法:

     renderChildren:function(notes,classes){ return notes.map(function (note) { //... 
  • 做了一個DeleteDialog組件。 它具有可重用的功能以及自己的呈現邏輯,將其分離出來可以提高代碼的可讀性:

     var DeleteDialog=React.createClass({ render:function(){ var classes=this.props.classes; return <div style={hideIfFalse(this.props.toggleDeleteDialogs)}> <button onClick={this.props.onDelete} className="half"> Yes </button>, <button className="half" onClick={this.props.onCancelDelete}> No </button> </div> } }); 
  • 我沒有觸及classSet邏輯,但不了解它應該做什么。

全部放在一起

   var hideIfFalse=function(boolean){
        return boolean? {} : {display : 'none'};
    };

    var notepad = {
      notes:
      [
          {
              id: 1,
              content: "Hello, world!\nBoring.\nBoring.\nBoring."
          },
          {
              id: 2,
              content: "React is awesome.\nSeriously, it's the greatest."
          },
          {
              id: 3,
              content: "Robots are pretty cool.\nRobots are awesome, until they take over."
          },
          {
              id: 4,
              content: "Monkeys.\nWho doesn't love monkeys?"
          }
      ],
      selectedId: 1
    };

    var DeleteDialog=React.createClass({
      render:function(){
        var classes=this.props.classes;

        return <div style={hideIfFalse(this.props.toggleDeleteDialogs)}>
              <button onClick={this.props.onDelete} className="half">
                Yes
              </button>,
              <button className="half" onClick={this.props.onCancelDelete}>
                No
              </button>
        </div>
      }

    })

    var NotesList = React.createClass({
      getInitialState: function() {
        return {
          isConfirming: false
        };
      },

      onSelectNote: function(id) {
          notepad.selectedId = id;
      },

      deleteThisNote: function(noteId) {
        if(this.state.isConfirming) {
          // actual delete functionality should be here
          this.setState({isConfirming: false});
        }
        else {
          this.setState({isConfirming: true});
        }
      },

      onCancelDelete: function() {
        this.setState({ isConfirming: false });
      },
      renderChildren:function(notes,classes){
        return  notes.map(function (note) {
                var title = note.content.substring(0, note.content.indexOf("\n"));
                title = title || note.content;
                var toggleDeleteDialogs = this.state.isConfirming && note.id === notepad.selectedId;
                var disableDelete = this.state.isConfirming && note.id !== notepad.selectedId;
                  return <li key={note.id}
                          onClick={this.onSelectNote.bind(null, note.id)} 
                          className="topcoat-list__item">
                          {title}
                            <button key={note.id} onClick={this.deleteThisNote.bind(null, note.id)} className="full" disabled={disableDelete ? "disabled" : ""}>Delete Note</button>
                            <DeleteDialog
                            toggleDeleteDialogs={toggleDeleteDialogs}
                            note={note}
                            onDelete={this.deleteThisNote.bind(null, note.id)}
                            onCancelDelete={this.onCancelDelete.bind(this)} />
                         </li>
                }.bind(this))
      },

      render: function() {
        var notes = notepad.notes;
        var cx = React.addons.classSet;
        var classes = cx({
          "topcoat-button-bar__button": true,
          "full": !this.state.isConfirming,
          "half": this.state.isConfirming,
        });

        return (
          <div className="topcoat-list">
            <ul className="topcoat-list__container">
              {this.renderChildren(notes,classes)}
            </ul>
          </div>
        );
      }
    });

    React.render(<NotesList />, document.getElementById('container'));

JSFiddle: http : //jsfiddle.net/55fvpcLo/2/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM