我第一次摆弄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);

当前回答

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

// 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钩子在块内部设置I信号。 我相信useState、useeffect和useRef钩子的实现允许您通过使用自定义钩子将它们分开来避免组件呈现。

希望这些知识对你有用。

其他回答

在状态中设置一个布尔值(例如:'show)',然后执行:

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

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

只要找到一种新的、神奇的方法来使用(useReducer)功能组件

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

如果你想看看如何TOGGLE显示一个组件签出这小提琴。

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

2020年左右的反应

在onClick回调中,调用状态钩子的setter函数来更新状态并重新呈现:

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>

JSFiddle

大约2014年

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

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>

JSFiddle

以下是我的方法。

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为true时才会呈现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”的原因;

While it might be 'cheaper' to hide an element with CSS - in such case 'hidden' element is still 'alive' in react world (which might make it actually way more expensive) it means that if props of the parent element (eg. <TabView>) will change - even if you see only one tab, all 5 tabs will get re-rendered the hidden element might still have some lifecycle methods running - eg. it might fetch some data from the server after every update even tho it's not visible the hidden element might crash the app if it'll receive incorrect data. It might happen as you can 'forget' about invisible nodes when updating the state you might by mistake set wrong 'display' style when making element visible - eg. some div is 'display: flex' by default, but you'll set 'display: block' by mistake with display: invisible ? 'block' : 'none' which might break the layout using someBoolean && <SomeNode /> is very simple to understand and reason about, especially if your logic related to displaying something or not gets complex in many cases, you want to 'reset' element state when it re-appears. eg. you might have a slider that you want to set to initial position every time it's shown. (if that's desired behavior to keep previous element state, even if it's hidden, which IMO is rare - I'd indeed consider using CSS if remembering this state in a different way would be complicated)