Hiển thị hoặc ẩn phần tử trong React


532

Tôi gặp rắc rối với React.js lần đầu tiên và không thể tìm cách hiển thị hoặc ẩn thứ gì đó trên trang thông qua sự kiện nhấp chuột. Tôi không tải bất kỳ thư viện nào khác vào trang, vì vậy tôi đang tìm một số cách riêng bằng thư viện React. Đây là những gì tôi có cho đến nay. Tôi muốn hiển thị kết quả div khi sự kiện nhấp chuột kích hoạt.

var Search= React.createClass({
    handleClick: function (event) {
        console.log(this.prop);
    },
    render: function () {
        return (
            <div className="date-range">
                <input type="submit" value="Search" onClick={this.handleClick} />
            </div>
        );
    }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);

11
Nhận xét được chấp nhận sử dụng công nghệ mới để thực hiện những gì công nghệ hiện có ở cấp độ bản địa có thể thực hiện dễ dàng hơn, nhanh hơn và dễ dàng hơn với các ngôn ngữ và thư viện khác. Xử lý điều này với CSS tiêu chuẩn gần như chắc chắn là câu trả lời tốt hơn.
John Haugeland

13
@JohnHaugeland, câu trả lời tốt nhất khi sử dụng khung React là câu trả lời được chấp nhận, đi theo tất cả kiểu React, có chức năng dọn dẹp mà trong một số trường hợp bạn phải làm. Nó không phải là thực hành tốt để có các thành phần chỉ ẩn trong bóng tối. Nếu bạn kết hợp các thứ, tốt hơn hết là bạn nên luôn luôn nhanh hơn mọi thứ khác.
Claudiu Hojda

4
Không, nó thực sự không. Sử dụng phản ứng để phát minh lại CSS là một ý tưởng tồi.
John Haugeland

8
Bên cạnh đó, bạn dường như đã hoàn toàn bỏ lỡ điểm tôi đã nói, đó là sử dụng CSS để ẩn và hiển thị phần tử, thay vì sử dụng React để loại bỏ vật lý. Bạn có thể sử dụng React để sử dụng CSS để ẩn và hiển thị phần tử một cách dễ dàng: <div style = {{display: this.props.example}} />.
John Haugeland

5
@ClaudiuHojda có các thành phần ẩn trong bóng tối thực sự rất tốt trong một số trường hợp, tôi đang nghĩ đến điều hướng phản ứng nhanh, nơi bạn cần các liên kết để ở lại HTML ngay cả khi chúng bị ẩn với css
Toni Leigh

Câu trả lời:


545

Phản ứng vào khoảng năm 2020

Trong cuộc onClickgọi lại, hãy gọi chức năng setter của hook trạng thái để cập nhật trạng thái và kết xuất lại:

const Search = () => {
  const [showResults, setShowResults] = React.useState(false)
  const onClick = () => setShowResults(true)
  return (
    <div>
      <input type="submit" value="Search" onClick={onClick} />
      { showResults ? <Results /> : null }
    </div>
  )
}

const Results = () => (
  <div id="results" className="search-results">
    Some Results
  </div>
)

ReactDOM.render(<Search />, document.querySelector("#container"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

Câu đố

Phản ứng vào khoảng năm 2014

Điều quan trọng là cập nhật trạng thái của thành phần trong trình xử lý nhấp bằng cách sử dụng setState. Khi thay đổi trạng thái được áp dụng, renderphương thức được gọi lại với trạng thái mới:

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

Câu đố


3
Vâng, điểm tốt về nhà nước vs đạo cụ. Một cách tốt hơn để làm điều này giống như trong hướng dẫn ở đây, nơi thanh tìm kiếm và bảng kết quả là anh em thay vì đặt Kết quả vào Tìm kiếm: facebook.github.io/react/docs/thinking-in-react.html
Douglas

53
Như đã lưu ý trong câu trả lời khác, việc chèn / xóa chậm hơn nhiều so với mặt nạ lớp đơn giản.
John Haugeland

4
Tôi nghĩ rằng ý kiến ​​của John cần xem xét lại. Tôi đã đi với câu trả lời dự định và đó là gọn gàng và 'cảm thấy' phản ứng nhiều hơn như thế. Tuy nhiên tôi không thể thiết lập trạng thái ban đầu và bất cứ điều gì hữu ích trên một thành phần chưa từng có. Tôi đang nhìn vào việc sử dụng css để ẩn những thứ thay thế. Người nghe trên các thành phần không thể đếm được sẽ âm thầm thất bại điều này đã gây ra cho tôi mất thời gian lớn ngày hôm nay.
hạ cánh

Điều đó có nghĩa là phản ứng sẽ chạy lại thành phần khi kiểu thay đổi (được đặt thành hiển thị / ẩn) !?
alex

@Doumund trừ khi tôi bỏ lỡ nó, cách này không cho phép chuyển trở lại ban đầu. Tôi đoán OP có thể không muốn nó nhưng làm thế nào tôi có thể bao gồm điều này?
Con sâu

221
<style type="text/css">
    .hidden { display:none; }
</style>
render: function() {
    return (
      <div className={this.props.shouldHide ? 'hidden' : ''}>
        This will be hidden if you set <tt>props.shouldHide</tt> 
        to something truthy.
      </div>
    );
}

// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>

12
Tốt hơn là trả lại có điều kiện null như trong câu trả lời của Douglas. Điều đó cho phép React loại bỏ nó hoàn toàn khỏi DOM. Trong trường hợp của bạn, div & nội dung của nó vẫn còn trong DOM chỉ không hiển thị. Điều này có thể có ý nghĩa hiệu suất.
pmont

125
Ý nghĩa về hiệu suất là tồi tệ hơn nhiều đối với việc thêm và xóa phần tử dom so với việc ẩn và hiển thị nó. Tôi nhận thức được sự khác biệt giữa cách tiếp cận của anh ấy và của tôi, và tôi tin rằng bạn có điều này hoàn toàn sai. Vui lòng xem xét dành thời gian để xác định "ý nghĩa hiệu suất" và sau đó đo lường nó.
John Haugeland

6
"Phản xạ được đảm bảo với thêm / xóa" - Không phải với các yếu tố được định vị tuyệt đối, đó là cách nổi tiếng có được hiệu suất đáng kinh ngạc của nó. Nhưng bạn thực hiện một điểm hợp lệ trên các số liệu.
pmont

9
Đối với những gì nó có giá trị, điều này được đề cập trong các tài liệu phản ứng ở đây: facebook.github.io/react/docs/ mẹo
Brad

85
Vì vậy, tôi chỉ thử nghiệm trả về null so với thiết lập một lớp ẩn với 161 nút dom khá lớn. Nó nhanh hơn đáng kể khi sử dụng một lớp so với loại bỏ nút.
Jonathan Rowny

120

Đây là một cú pháp thay thế cho toán tử ternary:

{ this.state.showMyComponent ? <MyComponent /> : null }

tương đương với:

{ this.state.showMyComponent && <MyComponent /> }

Lean tại sao


Ngoài ra cú pháp thay thế với display: 'none';

<MyComponent style={this.state.showMyComponent ? {} : { display: 'none' }} />

Tuy nhiên, nếu bạn quá lạm dụng display: 'none', điều này dẫn đến ô nhiễm DOM và cuối cùng làm chậm ứng dụng của bạn.


Cảnh báo! Chỉ sử dụng phương pháp 'nhân đôi và (&&)' cho các giá trị bool. {this.state.myComponents.length && <MyComponent />} sẽ hiển thị 0, nếu myComponents mảng trống (ví dụ)
Mega Proger

57

Đây là cách tiếp cận của tôi.

import React, { useState } from 'react';

function ToggleBox({ title, children }) {
  const [isOpened, setIsOpened] = useState(false);

  function toggle() {
    setIsOpened(wasOpened => !wasOpened);
  }

  return (
    <div className="box">
      <div className="boxTitle" onClick={toggle}>
        {title}
      </div>
      {isOpened && (
        <div className="boxContent">
          {children}
        </div>
      )}
    </div>
  );
}

Trong đoạn mã trên, để đạt được điều này, tôi đang sử dụng mã như:

{opened && <SomeElement />}

Điều đó sẽ SomeElementchỉ hiển thị nếu openedđúng. Nó hoạt động vì cách JavaScript giải quyết các điều kiện logic:

true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise (and false will be ignored by react during rendering)
// be careful with 'falsy' values eg
const someValue = 0;
someValue && <SomeElement /> // will output 0, which will be rednered by react
// it'll be better to:
!!someValue && <SomeElement /> // will render nothing as we cast the value to boolean

Lý do sử dụng phương pháp này thay vì CSS 'display: none';

  • Mặc dù có thể 'rẻ hơn' để ẩn một phần tử bằng CSS - trong trường hợp như vậy, phần tử 'ẩn' vẫn còn 'sống' trong thế giới phản ứng (điều này có thể khiến nó thực sự đắt hơn)
    • điều đó có nghĩa là nếu đạo cụ của phần tử cha (ví dụ. <TabView>) sẽ thay đổi - ngay cả khi bạn chỉ nhìn thấy một tab, tất cả 5 tab sẽ được kết xuất lại
    • phần tử ẩn vẫn có thể có một số phương thức vòng đời đang chạy - ví dụ: nó có thể lấy một số dữ liệu từ máy chủ sau mỗi lần cập nhật ngay cả khi nó không hiển thị
    • phần tử ẩn có thể làm sập ứng dụng nếu ứng dụng nhận được dữ liệu không chính xác. Nó có thể xảy ra khi bạn có thể 'quên' về các nút vô hình khi cập nhật trạng thái
    • bạn có thể do nhầm lẫn khi đặt sai kiểu 'hiển thị' khi hiển thị phần tử - ví dụ: một số div là 'display: flex' theo mặc định, nhưng bạn sẽ đặt 'display: block' do nhầm lẫn có display: invisible ? 'block' : 'none'thể phá vỡ bố cục
    • sử dụng someBoolean && <SomeNode />rất đơn giản để hiểu và lý do, đặc biệt là nếu logic của bạn liên quan đến việc hiển thị một cái gì đó hoặc không phức tạp
    • trong nhiều trường hợp, bạn muốn 'đặt lại' trạng thái phần tử khi nó xuất hiện lại. ví dụ. bạn có thể có một thanh trượt mà bạn muốn đặt về vị trí ban đầu mỗi khi nó được hiển thị. (nếu đó là hành vi mong muốn để giữ trạng thái phần tử trước đó, ngay cả khi nó bị ẩn, IMO rất hiếm - tôi thực sự cân nhắc sử dụng CSS nếu việc nhớ trạng thái này theo một cách khác sẽ phức tạp)

2
Đây là một ví dụ tuyệt vời! Một điều nhỏ, boxContent nên là className = "boxContent"
Bhetzie

5
Có một lỗi ngay tại đây : this.setState({isOpened: !isOpened});. Đừng phụ thuộc vào chính trạng thái, khi bạn sửa đổi trạng thái. Đây là một ví dụ hay: Reacjs.org/docs/. Vì vậy, nó phải là : this.setState( s => ({isOpened: !s.isOpened}) ). Lưu ý chức năng mũi tên bên trong setState.
arcol

Bạn có bất kỳ nguồn / điểm chuẩn / ví dụ nào xác nhận điều này "Nếu bạn đặt hiển thị: không - phần tử nào vẫn được hiển thị bằng phản ứng và được thêm vào DOM - có thể có tác động xấu đến hiệu suất." ?
neiya

@neiya Tôi không. CSS có thể hoạt động hiệu quả hơn với các yếu tố nhỏ, nhưng thường thì bạn muốn kết xuất các phần nội dung lớn tùy chọn, vd. chuyển hướng. Ngoài ra, trong khi một số phần tử bị ẩn bằng CSS - nó vẫn tồn tại trong thế giới phản ứng. Điều đó có nghĩa là nó có thể cập nhật trạng thái của nó, tìm nạp một số dữ liệu vv có thể tốn kém và dẫn đến hành vi không mong muốn. Và đó là IMO thực sự rất đơn giản để thực hiện.
pie6k


11

Tôi đã tạo một thành phần nhỏ xử lý việc này cho bạn: Reac-toggle-display

Nó đặt thuộc tính style display: none !importantdựa trên hidehoặc showđạo cụ.

Ví dụ sử dụng:

var ToggleDisplay = require('react-toggle-display');

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                <ToggleDisplay show={this.state.showResults}>
                    <Results />
                </ToggleDisplay>
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search />, document.body);

10

Đã có một số câu trả lời tuyệt vời, nhưng tôi không nghĩ rằng chúng đã được giải thích rất rõ và một số phương pháp được đưa ra có chứa một số vấn đề có thể khiến mọi người gặp rắc rối. Vì vậy, tôi sẽ đi qua ba cách chính (cộng với một tùy chọn ngoài chủ đề) để làm điều này và giải thích những ưu và nhược điểm. Tôi chủ yếu viết thư này vì Tùy chọn 1 được đề xuất rất nhiều và có rất nhiều vấn đề tiềm ẩn với tùy chọn đó nếu không được sử dụng đúng cách.

Tùy chọn 1: Kết xuất có điều kiện trong cha mẹ.

Tôi không thích phương pháp này trừ khi bạn chỉ kết xuất thành phần một lần và để nó ở đó. Vấn đề là nó sẽ gây ra phản ứng để tạo ra thành phần từ đầu mỗi khi bạn bật chế độ hiển thị. Đây là ví dụ. LogoutButton hoặc LoginButton đang được hiển thị một cách có điều kiện trong tệp cha mẹContControl. Nếu bạn chạy nó, bạn sẽ thấy hàm tạo sẽ được gọi trên mỗi nút bấm. https://codepen.io/Kelnor/pen/LzPdpN?editors=1111

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;

    let button = null;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Bây giờ React khá nhanh trong việc tạo các thành phần từ đầu. Tuy nhiên, nó vẫn phải gọi mã của bạn khi tạo nó. Vì vậy, nếu mã xây dựng, mã thành phần, kết xuất, vv của bạn đắt tiền, thì nó sẽ làm chậm đáng kể việc hiển thị thành phần. Điều đó cũng có nghĩa là bạn không thể sử dụng điều này với các thành phần trạng thái nơi bạn muốn trạng thái được bảo tồn khi ẩn (và được khôi phục khi hiển thị.) Một lợi thế là thành phần ẩn hoàn toàn không được tạo cho đến khi được chọn. Vì vậy, các thành phần ẩn sẽ không trì hoãn tải trang ban đầu của bạn. Cũng có thể có trường hợp bạn MUỐN một thành phần trạng thái để đặt lại khi bật. Trong trường hợp này đây là lựa chọn tốt nhất của bạn.

Tùy chọn 2: Kết xuất có điều kiện ở trẻ

Điều này tạo ra cả hai thành phần một lần. Sau đó ngắn mạch phần còn lại của mã kết xuất nếu thành phần bị ẩn. Bạn cũng có thể đoản mạch logic khác trong các phương pháp khác bằng cách sử dụng prop có thể nhìn thấy. Lưu ý console.log trong trang codepen. https://codepen.io/Kelnor/pen/YrKaWZ?editors=0011

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        <LoginButton isLoggedIn={isLoggedIn} onClick={this.handleLoginClick}/>
        <LogoutButton isLoggedIn={isLoggedIn} onClick={this.handleLogoutClick}/>
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    if(!this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    if(this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Bây giờ, nếu logic khởi tạo nhanh và trẻ em không trạng thái, thì bạn sẽ không thấy sự khác biệt về hiệu suất hoặc chức năng. Tuy nhiên, tại sao làm cho React tạo ra một thành phần hoàn toàn mới mỗi lần chuyển đổi? Tuy nhiên, nếu việc khởi tạo tốn kém, Tùy chọn 1 sẽ chạy nó mỗi khi bạn chuyển một thành phần sẽ làm chậm trang khi chuyển đổi. Tùy chọn 2 sẽ chạy tất cả các phần tử của thành phần khi tải trang đầu tiên. Làm chậm tải đầu tiên đó. Nên lưu ý lại. Nếu bạn chỉ hiển thị thành phần một lần dựa trên một điều kiện và không bật / tắt hoặc bạn muốn thiết lập lại khi bật, thì Tùy chọn 1 vẫn ổn và có lẽ là tùy chọn tốt nhất.

Tuy nhiên, nếu tải trang chậm là một vấn đề, điều đó có nghĩa là bạn đã có mã đắt tiền trong phương pháp vòng đời và đó thường không phải là một ý tưởng hay. Bạn có thể, và có lẽ nên, giải quyết tải trang chậm bằng cách di chuyển mã đắt tiền ra khỏi các phương thức vòng đời. Di chuyển nó đến một chức năng không đồng bộ được khởi động bởi ElementDidMount và gọi lại đặt nó vào một biến trạng thái với setState (). Nếu biến trạng thái là null và thành phần hiển thị thì có chức năng kết xuất trả về một trình giữ chỗ. Nếu không thì kết xuất dữ liệu. Bằng cách đó, trang sẽ tải nhanh và điền vào các tab khi chúng tải. Bạn cũng có thể di chuyển logic vào phụ huynh và đẩy kết quả cho trẻ làm đạo cụ. Bằng cách đó bạn có thể ưu tiên các tab nào được tải trước. Hoặc lưu trữ kết quả và chỉ chạy logic khi lần đầu tiên một thành phần được hiển thị.

Lựa chọn 3: Ẩn lớp

Lớp ẩn có lẽ là dễ thực hiện nhất. Như đã đề cập, bạn chỉ cần tạo một lớp CSS có hiển thị: không có và gán lớp dựa trên prop. Nhược điểm là toàn bộ mã của mọi thành phần ẩn được gọi và tất cả các thành phần ẩn được đính kèm vào DOM. (Tùy chọn 1 hoàn toàn không tạo ra các thành phần ẩn. Và Tùy chọn 2 ngắn mạch mã không cần thiết khi thành phần bị ẩn và loại bỏ hoàn toàn thành phần khỏi DOM.) Có vẻ như điều này nhanh hơn trong việc chuyển đổi khả năng hiển thị theo một số thử nghiệm được thực hiện bởi các nhà bình luận trên câu trả lời khác nhưng tôi không thể nói điều đó.

Tùy chọn 4: Một thành phần nhưng thay đổi Đạo cụ. Hoặc có thể không có thành phần nào cả và bộ đệm HTML.

Ứng dụng này sẽ không hoạt động cho mọi ứng dụng và nó không có chủ đề vì nó không phải là để ẩn các thành phần, nhưng nó có thể là một giải pháp tốt hơn cho một số trường hợp sử dụng hơn là ẩn. Hãy nói rằng bạn có các tab. Có thể viết một Thành phần Phản ứng và chỉ cần sử dụng các đạo cụ để thay đổi những gì được hiển thị trong tab. Bạn cũng có thể lưu JSX vào các biến trạng thái và sử dụng prop để quyết định JSX nào sẽ trả về trong hàm kết xuất. Nếu phải tạo ra JSX thì hãy thực hiện nó và lưu trữ nó trong tệp cha và gửi chính xác dưới dạng prop. Hoặc tạo trong đứa trẻ và lưu trữ nó trong trạng thái của trẻ và sử dụng đạo cụ để chọn một hoạt động.


9

Đây là một cách hay để sử dụng DOM ảo :

class Toggle extends React.Component {
  state = {
    show: true,
  }

  toggle = () => this.setState((currentState) => ({show: !currentState.show}));

  render() {
    return (
      <div>
        <button onClick={this.toggle}>
          toggle: {this.state.show ? 'show' : 'hide'}
        </button>    
        {this.state.show && <div>Hi there</div>}
      </div>
     );
  }
}

Ví dụ ở đây

Sử dụng móc React:

const Toggle = () => {
  const [show, toggleShow] = React.useState(true);

  return (
    <div>
      <button
        onClick={() => toggleShow(!show)}
      >
        toggle: {show ? 'show' : 'hide'}
      </button>    
      {show && <div>Hi there</div>}
    </div>
  )
}

Ví dụ ở đây


Tôi thích câu trả lời nạc này. Đáng tiếc các fiddle sẽ không chạy.
Juan Lanus

Như đã đề cập trong một câu trả lời trước đó, bạn khôngthis.setState() nên phụ thuộc vào trạng thái .
Dan Dascalescu

8

Bạn đặt giá trị boolean ở trạng thái (ví dụ: 'hiển thị)', sau đó thực hiện:

var style = {};
if (!this.state.show) {
  style.display = 'none'
}

return <div style={style}>...</div>

Tôi đã thử điều này, nhưng sự kiện nhấp không chuyển css sang khối hiển thị. Tôi bị mất chính xác làm thế nào để thực hiện nó. Bất kỳ lời khuyên bổ sung?
dùng1725382

1
Điều này liên quan đến việc thực hiện các thay đổi tích cực cho bảng quy tắc kiểu. Sẽ tốt hơn nhiều khi có một quy tắc hiện có duy nhất mà bạn có thể bật và tắt, đây không phải là một phần của các thuộc tính động của nút dom.
John Haugeland 30/1/2015

1
Nó thực sự không quan trọng nếu bạn sử dụng một lớp học hoặc phong cách ở đây ... bạn có vẻ rất quan tâm đến điều này.
Brigand

2
Sử dụng một lớp học là nhanh hơn bởi một vài đơn đặt hàng độ lớn. Thật tốt khi biết điều đó.
Jason Rice

1
Chỉ có thể sử dụng tên lớp có điều kiện với: github.com/JedWatson/
classnames

7

Thực hành tốt nhất là dưới đây theo tài liệu:

{this.state.showFooter && <Footer />}

Chỉ kết xuất phần tử khi trạng thái hợp lệ.


Câu trả lời này đã được đưa ra một năm trước, vì vậy bạn có thể xóa nó ngay bây giờ.
Dan Dascalescu

5
class Toggle extends React.Component {
  state = {
    show: true,
  }

  render() {
    const {show} = this.state;
    return (
      <div>
        <button onClick={()=> this.setState({show: !show })}>
          toggle: {show ? 'show' : 'hide'}
        </button>    
        {show && <div>Hi there</div>}
      </div>
     );
  }
}

4
   class FormPage extends React.Component{
      constructor(props){
           super(props);
           this.state = {
             hidediv: false
           }
      }

     handleClick = (){
       this.setState({
          hidediv: true
        });
      }

      render(){
        return(
        <div>
          <div className="date-range" hidden = {this.state.hidediv}>
               <input type="submit" value="Search" onClick={this.handleClick} />
          </div>
          <div id="results" className="search-results" hidden = {!this.state.hidediv}>
                        Some Results
           </div>
        </div>
        );
      }
  }

4

Tôi bắt đầu với tuyên bố này từ nhóm React:

Trong React, bạn có thể tạo các thành phần riêng biệt đóng gói hành vi bạn cần. Sau đó, bạn chỉ có thể kết xuất một số trong số chúng, tùy thuộc vào trạng thái của ứng dụng của bạn.

Kết xuất có điều kiện trong React hoạt động giống như cách các điều kiện hoạt động trong JavaScript. Sử dụng các toán tử JavaScript như if hoặc toán tử có điều kiện để tạo các phần tử đại diện cho trạng thái hiện tại và để React cập nhật giao diện người dùng để khớp với chúng.

Về cơ bản, bạn cần hiển thị thành phần khi nhấp vào nút, bạn có thể thực hiện theo hai cách, sử dụng React thuần túy hoặc sử dụng CSS, sử dụng cách React thuần túy, bạn có thể thực hiện một số thứ như mã bên dưới trong trường hợp của mình, vì vậy trong lần chạy đầu tiên, kết quả không hiển thị như hideResultstrue, nhưng bằng cách nhấp vào nút, tiểu bang sẽ thay đổi và hideResultsfalsevà get phần trả lại một lần nữa với điều kiện giá trị mới, đây là sử dụng rất phổ biến của việc thay đổi quan điểm thành phần trong Phản ứng ...

var Search = React.createClass({
  getInitialState: function() {
    return { hideResults: true };
  },

  handleClick: function() {
    this.setState({ hideResults: false });
  },

  render: function() {
    return (
      <div>
        <input type="submit" value="Search" onClick={this.handleClick} />
        { !this.state.hideResults && <Results /> }
      </div> );
  }

});

var Results = React.createClass({
  render: function() {
    return (
    <div id="results" className="search-results">
      Some Results
    </div>);
   }
});

ReactDOM.render(<Search />, document.body);

Nếu bạn muốn nghiên cứu sâu hơn về kết xuất có điều kiện trong React, hãy xem tại đây .


1
Đây là cách thanh lịch nhất!
thứ năm

4

Ví dụ ẩn / hiển thị đơn giản với React Hook: (srry about no fiddle)

const Example = () => {

  const [show, setShow] = useState(false);

  return (
    <div>
      <p>Show state: {show}</p>
      {show ? (
        <p>You can see me!</p>
      ) : null}
      <button onClick={() => setShow(!show)}>
    </div>
  );

};

export default Example;

2
nó có thể đơn giản hơn để chỉ {hiển thị? 1: 2}
Piotr Żak

3

Nếu bạn muốn xem làm thế nào để hiển thị màn hình của một thành phần kiểm tra fiddle này.

http://jsfiddle.net/mnoster/kb3gN/16387/

var Search = React.createClass({
    getInitialState: function() {
        return { 
            shouldHide:false
        };
    },
    onClick: function() {
        console.log("onclick");
        if(!this.state.shouldHide){
            this.setState({
                shouldHide: true 
            })
        }else{
                    this.setState({
                shouldHide: false 
            })
        }
    },
render: function() {
    return (
      <div>
        <button onClick={this.onClick}>click me</button>
        <p className={this.state.shouldHide ? 'hidden' : ''} >yoyoyoyoyo</p>
      </div>
    );
}
});

ReactDOM.render( <Search /> , document.getElementById('container'));

3

Một phương pháp đơn giản để hiển thị / ẩn các phần tử trong React bằng Hook

const [showText, setShowText] = useState(false);

Bây giờ, hãy thêm một số logic vào phương thức kết xuất của chúng tôi:

{showText && <div>This text will show!</div>}

onClick={() => setShowText(!showText)}

Làm tốt lắm.


2

Trong một số trường hợp, thành phần bậc cao hơn có thể hữu ích:

Tạo thành phần bậc cao hơn:

export var HidableComponent = (ComposedComponent) => class extends React.Component {
    render() {
        if ((this.props.shouldHide!=null && this.props.shouldHide()) || this.props.hidden)
            return null;
        return <ComposedComponent {...this.props}  />;
    }
};

Mở rộng thành phần của riêng bạn:

export const MyComp= HidableComponent(MyCompBasic);

Sau đó, bạn có thể sử dụng nó như thế này:

<MyComp hidden={true} ... />
<MyComp shouldHide={this.props.useSomeFunctionHere} ... />

Điều này làm giảm một chút nồi hơi và thực thi theo quy ước đặt tên, tuy nhiên xin lưu ý rằng MyComp vẫn sẽ được khởi tạo - cách bỏ qua đã được đề cập trước đó:

{ !hidden && <MyComp ... /> }


1

Sử dụng mô-đun RC-if- other

npm install --save rc-if-else
import React from 'react';
import { If } from 'rc-if-else';

class App extends React.Component {
    render() {
        return (
            <If condition={this.props.showResult}>
                Some Results
            </If>
        );
    }
}

1

Sử dụng ref và thao tác CSS

Một cách có thể là sử dụng React's refvà thao tác lớp CSS bằng API của trình duyệt. Lợi ích của nó là tránh việc đăng ký lại trong React nếu mục đích duy nhất là ẩn / hiển thị một số phần tử DOM khi nhấp vào nút.

// Parent.jsx
import React, { Component } from 'react'

export default class Parent extends Component {
    constructor () {    
        this.childContainer = React.createRef()
    }

    toggleChild = () => {
        this.childContainer.current.classList.toggle('hidden')
    }

    render () {
        return (
            ...

            <button onClick={this.toggleChild}>Toggle Child</button>
            <div ref={this.childContainer}>
                <SomeChildComponent/>
            </div>

            ...
        );
    }
}


// styles.css
.hidden {
    display: none;
}

PS Sửa tôi nếu tôi sai. :)


Đã tạo ví dụ Codeandbox.io, tại đây: utgzx.csb.app , mã có tại Codeandbox.io/embed/react-show- leather
with

0

Nếu bạn sử dụng bootstrap 4, bạn có thể ẩn phần tử theo cách đó

className={this.state.hideElement ? "invisible" : "visible"}

0

Điều này cũng có thể đạt được như thế này (cách rất dễ dàng)

 class app extends Component {
   state = {
     show: false
   };
 toggle= () => {
   var res = this.state.show;
   this.setState({ show: !res });
 };
render() {
  return(
   <button onClick={ this.toggle }> Toggle </button>
  {
    this.state.show ? (<div> HELLO </div>) : null
  }
   );
     }

Vui lòng đọc về cài đặt "trạng thái dựa trên trạng thái trước" tại Reacjs.org/docs/react-component.html#setstate . Ngoài ra, sẽ là tốt đẹp để sửa chữa vết lõm ở cuối.
Dan Dascalescu

0

ví dụ này cho thấy cách bạn có thể chuyển đổi giữa các thành phần bằng cách sử dụng chuyển đổi mà chuyển đổi sau mỗi 1 giây

import React ,{Fragment,Component} from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Component1 = () =>(
  <div>
    <img 
src="https://i.pinimg.com/originals/58/df/1d/58df1d8bf372ade04781b8d4b2549ee6.jpg" />
   </div>
)

const Component2 = () => {
  return (
    <div>
       <img 
src="http://www.chinabuddhismencyclopedia.com/en/images/thumb/2/2e/12ccse.jpg/250px- 
12ccse.jpg" />
  </div>
   )

 }

 class App extends Component {
   constructor(props) {
     super(props);
    this.state = { 
      toggleFlag:false
     }
   }
   timer=()=> {
    this.setState({toggleFlag:!this.state.toggleFlag})
  }
  componentDidMount() {
    setInterval(this.timer, 1000);
   }
  render(){
     let { toggleFlag} = this.state
    return (
      <Fragment>
        {toggleFlag ? <Component1 /> : <Component2 />}
       </Fragment>
    )
  }
}


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

URL hình ảnh kỳ lạ là gì? Bạn có thể sử dụng dịch vụ giữ chỗ hình ảnh tiêu chuẩn như placeimg.com
Dan Dascalescu

0

Sử dụng cú pháp nạc và ngắn này:

{ this.state.show && <MyCustomComponent /> }

Có lẽ bạn có thể mở rộng cú pháp nạc & ngắn của mình để giải thích cách hoạt động của nó. Oh chờ đợi, điều đó đã được thực hiện trong một câu trả lời 3 năm trước . Câu trả lời của bạn mang lại điều gì một lần nữa?
Dan Dascalescu

0

Ở đây có giải pháp đơn giản, hiệu quả và tốt nhất với Thành phần Phản ứng không phân loại để hiển thị / ẩn các phần tử. Sử dụng React-Hook có sẵn trong dự án ứng dụng tạo phản ứng mới nhất sử dụng React 16

import React, {useState} from 'react';
function RenderPara(){
const [showDetail,setShowDetail] = useState(false);

const handleToggle = () => setShowDetail(!showDetail);

return (
<React.Fragment>
    <h3>
        Hiding some stuffs 
    </h3>
    <button onClick={handleToggle}>Toggle View</button>
   {showDetail && <p>
        There are lot of other stuffs too
    </p>}
</React.Fragment>)

}  
export default RenderPara;

Chúc mừng mã hóa :)


0
//use ternary condition

{ this.state.yourState ? <MyComponent /> : null } 

{ this.state.yourState && <MyComponent /> }

{ this.state.yourState == 'string' ? <MyComponent /> : ''}

{ this.state.yourState == 'string' && <MyComponent /> }

//Normal condition

if(this.state.yourState){
 return <MyComponent />
}else{
  return null;
}

-1

Bạn có thể sử dụng tập tin css

    var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className={`search-results ${this.state.showResults ? 'show' : ''}`}>
                Some Results
            </div>
        );
    }
})

và trong tập tin css

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}

-1
var Search= React.createClass({
 getInitialState: () => { showResults: false },
 onClick: () => this.setState({ showResults: true }),
 render: function () {
   const { showResults } = this.state;
   return (
     <div className="date-range">
       <input type="submit" value="Search" onClick={this.handleClick} />
       {showResults && <Results />}
     </div>
   );
 }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);

1
Bạn có thể giải thích những gì bạn đã làm, và tại sao nó tốt hơn câu trả lời được chấp nhận?
Sablor

-1
class App extends React.Component {
  state = {
    show: true
  };

  showhide = () => {
    this.setState({ show: !this.state.show });
  };

  render() {
    return (
      <div className="App">
        {this.state.show && 
          <img src={logo} className="App-logo" alt="logo" />
        }
        <a onClick={this.showhide}>Show Hide</a>
      </div>
    );
  }
}

Bạn có thể vui lòng thêm giải thích để hiểu rõ hơn? Cảm ơn!
Chaieshwar Inde

@ShanteshwarInde: điều này sao chép cùng một ý tưởng từ câu trả lời trước đó , bao gồm cả việc sử dụng setState không chính xác tùy thuộc vào trạng thái hiện tại. Xem Reacjs.org/docs/react-component.html#setstate : "Nếu bạn cần đặt trạng thái dựa trên trạng thái trước đó, hãy đọc về đối số updater".
Dan Dascalescu

-1

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="checkbox" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                <input type="text" />
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>


4
Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và / hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó.
xiawi

Những gì @xiawi nói. Ngoài ra, vui lòng sử dụng constthay vì varkhi bạn khai báo hằng.
Dan Dascalescu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.