React:在onClick上调用两个事件处理程序并更改子组件的样式

时间:2017-07-02 16:30:49

标签: javascript reactjs ecmascript-6

我有一个基于父类的组件A和一个子功能组件B。在B内部,我映射一个名称列表并将它们呈现为li元素,onClick调用父组件中声明的onLanguageUpdate处理程序,以及此处理程序的作用是更新状态以反映所选名称。

问题

我需要在同一个onClick中调用第二个事件处理程序,这次要更改用户点击的名称的颜色。我向状态color添加了一个新属性,以表示className,然后我可以使用handleStyleColorChange处理程序切换。但是如何根据此处理程序的结果获取子组件中的li元素以更新其className(或样式)?如果我在组件A的render方法中执行了所有这些操作,我可以在style={language === this.state.selectedLanguage ? {color: 'red'} : null}上执行li并将其称为一天。

// Component A
import React, { Component } from 'react';
import B from './B';

class A extends Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedLanguage: 'All',
      color: 'lang-black-text'
    };
  }

  handleUpdateLanguage = (language) => {
    return this.setState({ selectedLanguage: language });
  }

  handleStyleColorChange = (language) => {
    if (language === this.state.selectedLanguage) {
      return this.setState({ color: 'lang-red-text' });
    } else {
      return this.setState({ color: 'lang-black-text' });
    }
  }

  handleClick = (language) => {
    this.handleUpdateLanguage(language);
    this.handleStyleColorChange(language);
  }

  render() {

    return (
      <LanguageList onLanguageUpdate={this.handleClick} />
    );
  }
}

export default A;
// Component B
import React from 'react';

const B = (props) => {
  const languages = ['English', 'Spanish', 'Japanese', 'Italian'];

  const languageListFormatted = languages.map(language => {
    return (
      <li
        key={language}
        onClick={() => props.onLanguageUpdate(language)}>{language}
      </li>
    );
  });

  return (
    <ul className="languages">{languageListFormatted}</ul>
  );
}

export default B;

1 个答案:

答案 0 :(得分:2)

您无法管理来自父comp的颜色,需要从子comp中完成。然后,将selectedLanguage发送给孩子,你很好。

class A extends React.Component {
  constructor(props) {
    super(props);

	  this.state = {
      selectedLanguage: 'All',
      color: 'lang-black-text'
    };
  }

  handleUpdateLanguage = (language) => {
    return this.setState({ selectedLanguage: language });
  }

  handleStyleColorChange = (language) => {
    if (language === this.state.selectedLanguage) {
      return this.setState({ color: 'lang-red-text' });
    } else {
      return this.setState({ color: 'lang-black-text' });
    }
  }

  handleClick = (language) => {
    this.handleUpdateLanguage(language);
    this.handleStyleColorChange(language);
  }

  render() {

    return (
      <B
        onLanguageUpdate={this.handleClick}
        selectedLanguage={this.state.selectedLanguage}
      />
    );
  }
}

const B = (props) => {
  const languages = ['English', 'Spanish', 'Japanese', 'Italian'];

  const languageListFormatted = languages.map(language => {
    return (
      <li
        key={language}
        style={props.selectedLanguage === language ? {background: 'yellow'} : {}}
        onClick={() => props.onLanguageUpdate(language)}>{language}
      </li>
    );
  });

  return (
    <ul className="languages">{languageListFormatted}</ul>
  );
}

ReactDOM.render(
  <A />,
  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>