【问题标题】:How can I change a specific component in React on an eventHandler如何在事件处理程序上更改 React 中的特定组件
【发布时间】:2017-10-12 23:26:19
【问题描述】:

我想要做的应该相当简单,但似乎我无法使用 this 获得对特定组件的引用

所以这里有我的 App.js

import React, { Component } from 'react';
import CoolBox from './coolBox.js';
import './App.css';

    class App extends Component {

      changeColor(){
        $(this).css('background','blue');
      }

      render() {
        return (
          <div className="App">
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
          </div>
        );
      }
    }

    export default App;

然后是 CoolBox.js,它只是一个带有红色背景的简单框:

import React, { Component } from 'react';
import $ from 'jquery';

class CoolBox extends Component {

  render() {
    return (
      <div onClick={this.props.changeColor} className="box"></div>
    );
  }
}

export default CoolBox;

看起来像这样:

现在我想要实现的是,当您单击 3 个框中的任何一个时,背景颜色将仅在被单击的特定框上发生变化。

如果 $(this) 无法引用,我似乎无法使用任何 jquery 方法。那么如何在 React 中实现这个简单的功能呢?

【问题讨论】:

  • 为什么要在App中定义changeColor方法?如果你在 Coolbox 中定义它,你应该可以使用普通的this。一般来说,不推荐以这种方式将 jQuery 混合到 React 中。如果你想要类似的东西,请使用 React 的 ref 功能。
  • 你应该避免使用 jQuery 和 React 一起改变 DOM。

标签: javascript jquery html css reactjs


【解决方案1】:

React 组件中的this 不是指 DOM 元素,而是指 Component 实例,因为给定组件的 DOM 可以由于状态或道具的改变而以任意方式改变。

正如@Chris 在上面的 cmets 中所提到的,你不应该将 jQuery 与你的 React 组件一起使用,除非你有充分的理由,并且你知道自己在做什么。

相反,您应该使用组件状态来声明您想要什么,然后在您的render() 方法中反映您的组件状态。

这是一个例子

class CoolBox extends React.Component {
  
  constructor(...args) {
    super(...args);
    this.state = {
      color: 'red'
    };
    
    this.changeColor = this.changeColor.bind(this);
  }
  
  changeColor() {
    this.setState({
      color: this.state.color === 'red' ? 'green' : 'red'
    });
  }
  
  render() {
    return <div 
      onClick={this.changeColor} 
      className="box"
      style={{backgroundColor: this.state.color}}
      ></div>
  }
}


class App extends React.Component {
  render() {
    return (
      <div>
        <CoolBox />
        <CoolBox />
        <CoolBox />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
.box {
  height: 100px;
  width: 100px;
  margin: 10px;
  display: inline-block;
}
<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>

【讨论】:

  • 嘿,非常感谢您的回复,非常感谢!您的解决方案是我最初想到的,但如果可能的话,我想避免在组件中使用样式,因为我在 SASS 中编写所有内容,并且会有大量的样式更改,因此它可以使事情变得更清洁。正如@Sag1v 在上面的答案中提到的,我可以使用 e.target 来定位事件上的元素,这可能是最接近复制 $(this) 的解决方案。因此,出于这个原因,我选择了他的答案,但您的答案仍然令人惊叹,并且也可以帮助许多其他人。所以 +1,谢谢!
  • 不用担心,很高兴您能够解决您的问题!
【解决方案2】:

你不需要 jQuery。 有几种方法可以引用 DOM 中的组件,并且您应该阅读这些组件的几种模式(受控和不受控)。
至于你的解决方案,这是一个简单的解决方案,只是为了让你开始。
在事件处理程序上,您可以访问 event 作为参数。 changeColor(e) as e 是保存事件信息的对象以及target(您在案例中单击的div)。
所以基本上你可以在App.js 做的是:

class App extends React.Component {
            constructor(props){
        super(props);
        this.changeColor = this.changeColor.bind(this);
      }
      changeColor(e){
        e.target.style.background = "blue";
      }

      render() {
        return (
          <div className="App">
            <CoolBox changeColor={this.changeColor} />
            <CoolBox changeColor={this.changeColor} />
            <CoolBox changeColor={this.changeColor} />
          </div>
        );
      }
    }  

请注意
如您所见,我将处理程序绑定在构造函数中,而不是 render 方法中。这样你只绑定一次,而不是在每个渲染调用上,女巫会在每个渲染上创建一个新实例。这对性能更好。

【讨论】:

  • 完全忘记了 e.target。非常感谢您的回答。我选择你的答案是因为它最接近 $(this)。 @rossipedia 也有一个了不起的解决方案,这绝对是人们应该考虑的问题,但就我的情况而言,我会选择你的 e.target 答案。谢谢!
猜你喜欢
  • 2017-06-14
  • 2014-01-27
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
相关资源
最近更新 更多