ChatGPT解决这个技术问题 Extra ChatGPT

在 React 中显示或隐藏元素

我第一次使用 React.js,找不到通过点击事件在页面上显示或隐藏某些内容的方法。我没有将任何其他库加载到页面中,因此我正在寻找使用 React 库的本地方式。这就是我到目前为止所拥有的。我想在点击事件触发时显示结果 div。

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);
接受的评论使用新颖的技术来完成本机级别的现有技术可以更轻松、更快且与其他语言和库共享的内容。使用标准 CSS 处理这个问题几乎可以肯定是更好的答案。
@JohnHaugeland,使用 React 框架时的最佳答案是公认的答案,采用所有 React 风格,它具有在某些情况下必须执行的清理功能。让组件隐藏在黑暗中并不是一个好习惯。如果你混合一些东西,你最好全部使用原生,这总是比其他任何东西都快。
不,真的不是。使用 react 来重新发明 CSS 是个坏主意。
此外,您似乎完全忽略了我所说的重点,即使用 CSS 隐藏和显示元素,而不是使用 React 物理删除它。您可以使用 React 来使用 CSS 轻松隐藏和显示元素:
@ClaudiuHojda 在某些情况下将组件隐藏在黑暗中实际上是非常好的做法,我正在考虑响应式导航,您需要将链接保留在 HTML 中,即使它们被 css 隐藏

D
Douglas

大约在 2020 年做出反应

onClick 回调中,调用 state hook's setter 函数来更新状态并重新渲染:

const Search = () => { const [showResults, setShowResults] = React.useState(false) const onClick = () => setShowResults(true) return (

{ showResults ? : null }
) } const Results = () => (
一些结果
) ReactDOM.render(, document.querySelector("#container"))

JSFiddle

大约 2014 年的反应

关键是使用 setState 在点击处理程序中更新组件的状态。当状态更改被应用时,render 方法被再次调用并使用新状态:

var Search = React.createClass({ getInitialState: function() { return { showResults: false }; }, onClick: function() { this.setState({ showResults: true }); }, render: function() { return (

{ this.state.showResults ? : null }
); } }); var Results = React.createClass({ render: function() { return (
一些结果
); } }); ReactDOM.render( , document.getElementById('container'));

JSFiddle


是的,关于状态与道具的好点。执行此操作的更好方法应该是此处的教程,其中搜索栏和结果表是同级的,而不是将结果放在搜索中:facebook.github.io/react/docs/thinking-in-react.html
如另一个答案所述,插入/删除比简单的类屏蔽要慢得多。
我认为约翰斯的评论需要审查。我选择了预期的答案,这很整洁,而且“感觉”更像是反应。但是,我无法在未安装的组件上设置初始状态和任何有用的东西。我正在考虑使用 css 来隐藏东西。未安装组件上的侦听器会默默地失败,这让我今天损失了很多时间。
这是否意味着当样式更改(设置为显示/隐藏)时,react 将重新渲染组件!?
代替 { showResults ? <Results /> : null } 可以做 { showResults && <Results /> }
J
John Haugeland
<style type="text/css">
    .hidden { display:none; }
</style>
const Example = props => 
  <div className={props.shouldHide? 'hidden' : undefined}>Hello</div>

最好像 Douglas 的回答那样有条件地返回 null。这允许 React 将其完全从 DOM 中删除。在您的情况下, div 及其内容仍在 DOM 中,只是没有显示。这可能会影响性能。
添加和删除 dom 元素对性能的影响比隐藏和显示它要糟糕得多。我知道他的方法和我的方法之间的区别,我相信你完全错了。请考虑花时间定义“性能影响”,然后对其进行衡量。
“通过添加/删除保证回流”——不是绝对定位的元素,这就是 Famous 获得其令人难以置信的性能的方式。但是您在指标上提出了一个有效的观点。
对于它的价值,这里的反应文档中提到了这一点:facebook.github.io/react/docs/…
所以我只是测试了返回 null 与设置一个具有 161 个相当大的 dom 节点的隐藏类。使用类比删除节点快得多。
S
StefanBob

这是三元运算符的另一种语法:

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

相当于:

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

Learn why

还有 display: 'none'; 的替代语法

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

但是,如果您过度使用 display: 'none',这会导致 DOM 污染并最终减慢您的应用程序。


警告!仅对 bool 值使用“双与号(&&)”方法。 { this.state.myComponents.length && } 将呈现 0,如果 myComponents 为空数组(例如)
@MegaProger 在这种情况下使用 !!{ !!this.state.myComponents.length && <MyComponent /> } 转换为布尔值
这在任何意义上都不是“三元运算符的替代语法”。这是有问题的,除了开头条款的双重否定之外,还有其他地方会导致问题。
在我看来,第二个例子是代码异味
A
Adam Pietrasiak

这是我的方法。

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>
  );
}

在上面的代码中,为了实现这一点,我使用如下代码:

{opened && <SomeElement />}

只有当 opened 为真时才会呈现 SomeElement。它之所以起作用,是因为 JavaScript 解析逻辑条件的方式:

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 = [];
someValue.length && <SomeElement /> // will output 0, which will be rednered by react
// it'll be better to:
someValue.length > 0 && <SomeElement /> // will render nothing as we cast the value to boolean

使用这种方法而不是 CSS 'display: none' 的原因;

虽然使用 CSS 隐藏元素可能“更便宜”——在这种情况下,“隐藏”元素在反应世界中仍然“活跃”(这可能使其实际上更加昂贵),这意味着如果父元素的道具(例如. ) 将会改变——即使你只看到一个选项卡,所有 5 个选项卡都将被重新渲染,隐藏的元素可能仍然有一些生命周期方法正在运行——例如。它可能会在每次更新后从服务器获取一些数据,即使它不可见,如果隐藏元素接收到不正确的数据,它可能会使应用程序崩溃。这可能会发生,因为您在更新状态时可能会“忘记”不可见的节点,您可能会在使元素可见时错误地设置错误的“显示”样式 - 例如。某些 div 默认为 'display: flex',但您会错误地将 'display: block' 设置为 display: invisible ? 'block' : 'none' 这可能会破坏使用 someBoolean && 的布局非常容易理解和推理,特别是如果您的逻辑与显示或不显示某些内容在许多情况下变得复杂,您想要“重置”重新出现时的元素状态。例如。您可能有一个滑块,每次显示时都希望将其设置为初始位置。 (如果这是保持先前元素状态的理想行为,即使它是隐藏的,这在 IMO 中很少见——如果以不同的方式记住这个状态会很复杂,我确实会考虑使用 CSS)

这意味着如果父元素的道具(例如 )发生变化 - 即使您只看到一个选项卡,所有 5 个选项卡都会重新渲染

隐藏元素可能仍在运行一些生命周期方法 - 例如。它可能会在每次更新后从服务器获取一些数据,即使它不可见

如果隐藏的元素接收到不正确的数据,它可能会导致应用程序崩溃。这可能会发生,因为您可以在更新状态时“忘记”不可见的节点

在使元素可见时,您可能会错误地设置错误的“显示”样式 - 例如。某些 div 默认为 'display: flex',但您会错误地将 'display: block' 设置为 display: invisible ? 'block' : 'none' 这可能会破坏布局

使用 someBoolean && 非常容易理解和推理,尤其是当您与显示或不显示某些内容相关的逻辑变得复杂时

在许多情况下,您希望在元素状态重新出现时“重置”它。例如。您可能有一个滑块,每次显示时都希望将其设置为初始位置。 (如果这是保持先前元素状态的理想行为,即使它是隐藏的,这在 IMO 中很少见——如果以不同的方式记住这个状态会很复杂,我确实会考虑使用 CSS)


这是一个很好的例子!一件小事,boxContent 应该是 className="boxContent"
这里有一个错误:this.setState({isOpened: !isOpened});。当你修改状态时,不要依赖状态本身。这是一个很好的例子:reactjs.org/docs/… 所以它应该是:this.setState( s => ({isOpened: !s.isOpened}) )。注意 setState 中的箭头函数。
您是否有任何来源/基准/示例确认此“如果您设置显示:无 - 元素仍由反应呈现并添加到 DOM - 这可能会对性能产生不良影响。” ?
@neiya 我没有。 CSS 可能对小元素有更高的性能,但通常您希望呈现可选的大部分内容,例如。标签。此外,虽然某些元素被 CSS 隐藏了——但它在反应世界中仍然存在。这意味着它可能会更新其状态、获取一些数据等,这可能会很昂贵并导致意外行为。 IMO 实际上实现起来非常简单。
S
Silicum Silium

使用最新版本的 react 0.11,您也可以只返回 null 以不呈现任何内容。

Rendering to null


仅链接的响应应作为评论发布,而不是“答案”。要获得作为答案的资格,请包含链接页面中的相关信息。如果页面变得不可访问,或者如果它的内容发生变化,这个响应将变得毫无用处。 SO上的所有答案都必须是自给自足的,不需要外部资源来阅读解决方案。如果问题属于适合编码答案的类型,则必须将解决问题所需的确切代码嵌入答案中。
请更新以包含解决 OP 问题的“所需的确切代码”示例,如 SO 指南中所述。
d
daniloprates

这是利用虚拟 DOM 的好方法:

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>
     );
  }
}

示例 here

使用 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>
  )
}

示例 here


我喜欢这个简洁的答案。可惜小提琴不会运行。
如前面的答案所述,您应该not depend on state in this.setState()
简单而有效的钩子
S
Silicum Silium

我为您创建了一个小组件来处理这个问题:react-toggle-display

它根据 hideshow 属性将样式属性设置为 display: none !important

示例用法:

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);

K
Kelnor

已经有几个很好的答案,但我认为它们没有得到很好的解释,并且给出的几种方法包含一些可能会绊倒人们的陷阱。因此,我将介绍三种主要方式(外加一个题外话选项)并解释其优缺点。我之所以写这篇文章,主要是因为很多人推荐了选项 1,如果使用不当,该选项会出现很多潜在问题。

选项 1:父级中的条件渲染。

我不喜欢这种方法,除非您只打算渲染一次组件并将其留在那里。问题是每次切换可见性时都会导致从头开始创建组件的反应。这是示例。 LogoutButton 或 LoginButton 在父 LoginControl 中有条件地呈现。如果你运行它,你会注意到构造函数在每次按钮点击时被调用。 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')
);

现在 React 在从头开始创建组件方面非常快。但是,它仍然必须在创建它时调用您的代码。因此,如果您的构造函数、componentDidMount、render 等代码很昂贵,那么它会显着减慢组件的显示速度。这也意味着您不能将它与您希望在隐藏时保留状态(并在显示时恢复)的有状态组件一起使用。一个优点是隐藏组件在被选中之前根本不会创建。因此隐藏组件不会延迟您的初始页面加载。在某些情况下,您可能希望在切换时重置有状态组件。在这种情况下,这是您的最佳选择。

选项 2:子项中的条件渲染

这将创建两个组件一次。如果组件被隐藏,则将其余的渲染代码短路。您还可以使用 visible 道具在其他方法中短路其他逻辑。注意 codepen 页面中的 console.log。 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')
);

现在,如果初始化逻辑很快并且子节点是无状态的,那么您将不会看到性能或功能上的差异。但是,为什么要让 React 每次切换都创建一个全新的组件呢?但是,如果初始化成本很高,则每次切换组件时选项 1 都会运行它,这会在切换时减慢页面速度。选项 2 将在第一页加载时运行所有组件的初始化。减慢第一个负载。应再次注意。如果您只是根据条件显示组件一次而不切换它,或者您希望它在切换时重置,那么选项 1 很好,可能是最好的选择。

但是,如果页面加载缓慢是一个问题,则意味着您在生命周期方法中拥有昂贵的代码,这通常不是一个好主意。您可以并且可能应该通过将昂贵的代码移出生命周期方法来解决页面加载缓慢的问题。将其移至由 ComponentDidMount 启动的异步函数,并让回调将其放入带有 setState() 的状态变量中。如果状态变量为 null 并且组件可见,则让渲染函数返回一个占位符。否则渲染数据。这样,页面将快速加载并在加载时填充选项卡。您还可以将逻辑移动到父级并将结果作为道具推送给子级。这样,您可以优先考虑首先加载哪些选项卡。或者缓存结果并仅在第一次显示组件时运行逻辑。

选项 3:类隐藏

类隐藏可能是最容易实现的。如前所述,您只需创建一个带有 display: none 的 CSS 类并根据 prop 分配该类。缺点是调用每个隐藏组件的整个代码,并且所有隐藏组件都附加到 DOM。 (选项 1 根本不创建隐藏的组件。选项 2 在隐藏组件时会缩短不必要的代码并从 DOM 中完全删除组件。)根据评论者所做的一些测试,这似乎在切换可见性方面更快其他答案,但我不能说。

选项 4:一个组件但更改道具。或者可能根本没有组件并缓存 HTML。

这个不适用于每个应用程序,并且它不是主题,因为它不是隐藏组件,但对于某些用例来说,它可能是比隐藏更好的解决方案。假设您有标签。可以编写一个 React 组件,然后使用道具来更改选项卡中显示的内容。您还可以将 JSX 保存到状态变量中,并使用 prop 来决定在渲染函数中返回哪个 JSX。如果必须生成 JSX,则执行此操作并将其缓存在父级中,并将正确的一个作为道具发送。或者在child中生成并缓存在child的状态中,并使用props选择活动的。


B
Brigand

您在状态中设置一个布尔值(例如“显示”),然后执行以下操作:

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

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

我试过这个,但是点击事件没有将css切换到显示块。我不知道如何完成它。任何额外的提示?
这涉及对样式规则表进行主动更改。最好有一个可以打开和关闭的现有规则,这不是 dom 节点的动态属性的一部分。
如果你在这里使用一个类或风格真的没关系......你似乎对此非常着迷。
使用一个类要快几个数量级。很高兴知道。
可以只使用条件类名称:github.com/JedWatson/classnames
s
superup

使用 Hooks 在 React 中显示/隐藏元素的简单方法

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

现在,让我们为我们的渲染方法添加一些逻辑:

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

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

好工作。


这个最好!
r
ravibagul91

根据文档,最佳实践如下:

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

仅当状态有效时才渲染元素。


这个答案在一年前已经是 given,所以现在可以删除它。
S
StefanBob

使用 React Hooks 的简单隐藏/显示示例:(请不要提琴)

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;

f
farynaa

我能够使用css属性“隐藏”。不知道可能的缺点。

export default function App() {
    const [hidden, setHidden] = useState(false);
    return (
      <div>
        <button onClick={() => setHidden(!hidden)}>HIDE</button>
        <div hidden={hidden}>hidden component</div>
      </div>
    );
  }

A
Akanksha gore
   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>
        );
      }
  }

A
Alireza

我从 React 团队的声明开始:

在 React 中,您可以创建不同的组件来封装您需要的行为。然后,您可以只渲染其中的一部分,具体取决于您的应用程序的状态。 React 中条件渲染的工作方式与 JavaScript 中条件的工作方式相同。使用 if 或条件运算符等 JavaScript 运算符创建表示当前状态的元素,并让 React 更新 UI 以匹配它们。

您基本上需要在单击按钮时显示组件,您可以通过两种方式进行操作,使用纯 React 或使用 CSS,使用纯 React 方式,您可以在您的案例中执行类似以下代码的操作,因此在第一次运行时,结果没有显示为 hideResultstrue,但是通过单击按钮,状态会发生变化并且 hideResultsfalse 并且组件会以新的值条件再次呈现,这是更改组件的非常常见的用法在 React 中查看...

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);

如果您想进一步研究 React 中的条件渲染,请查看 here


这应该是最优雅的方式!
s
sgr
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>
     );
  }
}

N
Nicholas Porter

如果您想了解如何切换组件的显示,请查看此小提琴。

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'));

U
UtkarshPramodGupta

使用 ref 并操作 CSS

一种方法是使用 React 的 ref 并使用浏览器的 API 操作 CSS 类。如果唯一的目的是在单击按钮时隐藏/显示某些 DOM 元素,它的好处是避免在 React 中重新渲染。

// 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如果我错了,请纠正我。 :)


创建了 codesandbox.io 示例,此处:utgzx.csb.app,代码位于 codesandbox.io/embed/react-show-hide-with-css-utgzx
虽然它肯定会起作用,但它被认为是操纵 DOM 的反模式,除非您别无选择,例如在集成不兼容的 3rd-party 库时,如旧的 jQuery 小部件等。
你是绝对正确的@EmileBergeron。当您不愿意在组件中引入 State 时,这是一种未优化的方法。当我还是 React 的新手时,它写了答案 2 年前。
v
vinga

在某些情况下,高阶组件可能有用:

创建高阶组件:

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}  />;
    }
};

扩展您自己的组件:

export const MyComp= HidableComponent(MyCompBasic);

然后你可以像这样使用它:

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

这减少了一些样板文件并强制遵守命名约定,但是请注意 MyComp 仍将被实例化 - 前面提到了省略的方法:

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


T
ThomasP1988

如果你使用 bootstrap 4,你可以这样隐藏元素

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

q
qinyuanbin

使用 rc-if-else 模块

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>
        );
    }
}

Z
Zayn

使用这种简洁而简短的语法:

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

也许你可以扩大你的精益和简短的语法来解释它是如何工作的。哦,等等,这是在答案 3 years earlier 中完成的。你的回答又带来了什么?
R
Remi Prasanna

这是一个简单、有效和最佳的解决方案,它带有一个用于显示/隐藏元素的无类 React 组件。使用 React-Hooks,它在使用 React 16 的最新 create-react-app 项目中可用

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;

快乐编码:)


N
Naved Khan
//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;
}


<button onClick={()=>this.setState({yourState: !this.props.yourState}>Toggle View</button>

a
ahmed mersal

只需找出一种新的神奇方式使用(useReducer)功能组件

const [state, handleChangeState] = useReducer((state) => !state, false);改变状态


M
Mohammad Basit

这也可以这样实现(非常简单的方法)

 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
  }
   );
     }

请阅读 reactjs.org/docs/react-component.html#setstate 中有关设置“基于先前状态的状态”的信息。另外,最好在最后修复缩进。
S
Snivio

此示例展示了如何使用每 1 秒切换一次的切换开关在组件之间切换

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 是怎么回事?您可以使用标准图像占位符服务,例如 placeimg.com
J
Jorge Pirela

状态和效果的应用已经并且必须封装在同一个组件中,因此,没有什么比创建自定义组件作为钩子来解决在这种情况下是否使特定块或元素可见或不可见更好的了。

// hooks/useOnScreen.js

import { useState, useEffect } from "react"

const useOnScreen = (ref, rootMargin = "0px") => {

  const [isVisible, setIsVisible] = useState(false)

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        setIsVisible(entry.isIntersecting)
      },
      {
        rootMargin
      }
    );

    const currentElement = ref?.current

    if (currentElement) {
      observer.observe(currentElement)
    }

    return () => {
      observer.unobserve(currentElement)
    }
  }, [])

  return isVisible
}

export default useOnScreen

然后自定义钩子嵌入到组件内部

import React, { useRef } from "react";
import useOnScreen from "hooks/useOnScreen";

const MyPage = () => {

  const ref = useRef(null)

  const isVisible = useOnScreen(ref)

  const onClick = () => {
    console.log("isVisible", isVisible)
  }
  
  return (
    <div ref={ref}>
      <p isVisible={isVisible}>
        Something is visible
      </p>
      <a
        href="#"
        onClick={(e) => {
          e.preventDefault();
          onClick(onClick)
        }}
      >
        Review
      </a>
    </div>
  )
}

export default MyPage

由 useRef 钩子控制的 ref 变量允许我们捕获我们想要控制的块在 DOM 中的位置,然后由 useOnScreen 钩子控制的 isVisible 变量允许我们通过useRef 钩子。我相信 useState、useEfect 和 useRef 钩子的这种实现允许您通过使用自定义钩子分隔它们来避免组件渲染。

希望这些知识对你有用。


F
Force Bolt
// Try this way

class App extends Component{

  state = {
     isActive:false
  }

  showHandler = ()=>{
      this.setState({
          isActive: true
      })
  }

  hideHandler = () =>{
      this.setState({
          isActive: false
      })
  }

   render(){
       return(
           <div>
           {this.state.isActive ? <h1>Hello React jS</h1> : null }
             <button onClick={this.showHandler}>Show</button>
             <button onClick={this.hideHandler}>Hide</button>
           </div>
       )
   }
}

A
Alan Paul Mathew
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);

你能解释一下你做了什么,为什么它比公认的答案更好?