将事件侦听器状态作为道具传递

时间:2018-10-05 12:20:22

标签: javascript reactjs

在我的React代码中,我正在使用Babel的第3阶段类属性,该属性不需要构造函数来声明状态和事件侦听器。父组件具有两个状态:colorlistener。现在的问题是,作为this.state.listener道具传递的clickEvent无法正常工作。

下面的代码应该在每次单击时将按钮的颜色从白色更改为黑色,反之亦然。

const Button = props => {
  const { background, clickEvent } = props;
  const styles = {
    background,
    color: background === '#000' ? '#fff' : '#000'
  };

  return <button style={styles} onClick={clickEvent}>Change color</button>
}



export default class App extends Component {
  state = {
    color: '#fff',
    listener: this.changeColor
  }

  changeColor = () => {
    this.setState(state => ({
      color: state.color === '#000' ? '#fff' : '#000'
    }))
  }

  render() {
    const { color, listener } = this.state;

    return (
      <Button background={color} clickEvent={listener} />
    )
  }
}

3 个答案:

答案 0 :(得分:1)

您不应在状态中存储函数,即变量。您应将changeColor函数传递给子道具,如下所示:

const Button = props => {
  const { background, clickEvent } = props;
  const styles = {
    background,
    color: background === '#000' ? '#fff' : '#000'
  };

  return <button style={styles} onClick={clickEvent}>Change color</button>
}



export default class App extends Component {
  state = {
    color: '#fff',
  }

  changeColor = () => {
    this.setState(state => ({
      color: state.color === '#000' ? '#fff' : '#000'
    }))
  }

  render() {
    const { color } = this.state;

    return (
      <Button background={color} clickEvent={this.changeColor} />
    )
  }
}

答案 1 :(得分:0)

只需直接使用该方法即可,

export default class App extends Component {
  state = {
    color: '#fff'
  }

  changeColor = () => {
    this.setState(state => ({
      color: state.color === '#000' ? '#fff' : '#000'
    }))
  }

  render() {
    const { color, listener } = this.state;

    return (
      <Button background={color} clickEvent={this.changeColor} /> //fixed
    )
  }
}

我们不需要将其设置为state属性。

答案 2 :(得分:0)

它不起作用的原因是您按错误的顺序执行操作。您先声明this.state,然后再声明this.changeColor,所以您试图在定义之前访问this.changeColor。因此,如果您想继续将其存储在状态中(我同意其他人的看法是不必要的),则需要交换其顺序:

export default class App extends Component {
  changeColor = () => {
    this.setState(state => ({
      color: state.color === '#000' ? '#fff' : '#000'
    }))
  }

  state = {
    color: '#fff',
    listener: this.changeColor
  }

  render() {
    const { color, listener } = this.state;

    return (
      <Button background={color} clickEvent={listener} />
    )
  }
}