【问题标题】:react-dom: Incrementally change opacity of an element on clickreact-dom:在点击时逐渐改变元素的不透明度
【发布时间】:2018-10-16 03:22:04
【问题描述】:

我希望能够在单击按钮时增加 DOM 元素的不透明度

围绕 React 的概念,我认为这应该通过使用 state 和函数式 setState() 函数来完成。

但是,我不断遇到以下代码错误:

import React, { Component } from 'react'

class ThoughtfulThoughts extends Component {

  state = {
    opacity: 0.4,
    thoughts:
      [
        "live and let leave",
        "just pee yourself",
        "who knows what 'laf' is?"
      ]
  }

  makeAppear = () => {
    // TODO: this causes a "RangeError: Maximum call stack size exceeded"
    this.setState(prevState => ({
      opacity: prevState.opacity + 0.2
    }))
  }

  render() {
    return (
      <div className="thoughtful-thoughts">
        <div className="current-thought" style={{opacity: this.state.opacity}}>
          {this.state.thoughts.map((thought, i) => (<p>{thought}</p>))}
        </div>
        <button onClick={this.makeAppear()}>Think for me</button>
      </div>
    )

  }
}

export default ThoughtfulThoughts

不想use jQuery,也不想direct DOM manipulation,也不想 CSS transitions,但想以“React 方式”在 JS 中执行此操作。

任何指针将不胜感激!

【问题讨论】:

  • onClick={this.makeAppear()}改成onClick={this.makeAppear}
  • ^ 克里斯所说的。扩展它,超出堆栈大小的原因是因为每次渲染时,您都在调用该函数onClick={this.makeAppear()}。该函数会更改状态,从而导致重新渲染。这种重新渲染调用该函数,它会改变状态——等等。这是一个无限循环。
  • 你还需要用() 包裹{ opacity: prevState.opacity + 0.2 } 否则使用return。

标签: reactjs opacity


【解决方案1】:

您的代码中有几个小问题:

  1. 在您的按钮组件上,将onClick={this.makeAppear()} 更改为onClick={this.makeAppear}

  2. 很好地使用函数方法而不是对象方法根据先前的状态变量更新状态变量。但是,您有一个次要语法。要么做:

    this.setState(prevState => (
      {opacity: prevState.opacity + 0.2}
    ));
    

    this.setState(prevState => {
      return {opacity: prevState.opacity + 0.2}
    });
    

    随你喜欢。

  3. 为您从map() 返回的每个项目添加一个key 属性:所以基本上:

    {this.state.thoughts.map((thought, i) => (<p key={i}>{thought}</p>))}
    

    您可以在这里安全地使用i 作为键,因为thoughts 数组中项目的顺序将保持不变。有关密钥以及如何正确使用它们的更多信息,请查看here


演示:

class ThoughtfulThoughts extends React.Component {
  constructor() {
    super();
    this.state = {
      opacity: 0.4,
      thoughts:
        [
          "live and let leave",
          "just pee yourself",
          "who knows what 'laf' is?"
        ]
    }
  }

  makeAppear = () => {
    this.setState(
      prevState => ({opacity: prevState.opacity + 0.2})
    );
  }

  render() {
    return (
      <div className="thoughtful-thoughts">
        <div className="current-thought" style={{opacity: this.state.opacity}}>
          {this.state.thoughts.map((thought, i) => <p key={i}>{thought}</p>)}
        </div>
        <button onClick={this.makeAppear}>Think for me</button>
      </div>
    );
  }
}

ReactDOM.render(<ThoughtfulThoughts />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2016-08-20
    • 2013-09-19
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多