【问题标题】:'onChange' event is getting called only once in react'onChange' 事件在反应中只被调用一次
【发布时间】:2019-04-18 18:30:54
【问题描述】:

我正在使用material-ui

我的反应组件在这里:

import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import React from "react";
import { withStyles } from "@material-ui/core/styles";

const styles = (theme) => ({
});

class SomeComponent extends React.Component {
  static propTypes = {

  };

  state = {
    checked: true,
  }

  handleChange = name => event => {        
    event.persist()
    this.setState({ 
      [name]: event.target.checked 
    }, () => {
      if (event.target.checked) {
        this.props.parentMethod1(event.target.value)
      } else {
        this.props.parentMethod2(event.target.value)
      }
    });
  };

  render() {
    const { user } = this.props;
    return (
      <div>
        <FormControlLabel
          control={
            <Checkbox
              checked={this.state.checked}
              onChange={this.handleChange('checked')}
              value={user.id}
              color="primary"
            />
          }
          label={user.first_name}
        />
      </div>
    );
  }

}

export default withStyles(styles)(SomeComponent);

问题是,我只能选择/取消选择复选框一次。 选择/取消选择复选框后,不会发生 onChange 事件。

您能帮助我如何使 Checkbox 能够正常工作吗? 谢谢。

这里是重现的错误:

https://codesandbox.io/s/y041zknrqv

【问题讨论】:

  • 不要在回调中使用event.target.checkedevent.target.value,您可以将checkedvalue放入变量中,这是您在从handleChange返回的函数中所做的第一件事:@987654330 @ 并改用它。这样你就不需要持久化事件。这能解决问题吗?
  • 这将删除警告,但问题尚未解决。
  • 您好。我似乎无法使用与您类似的代码重现该问题:codesandbox.io/s/m788313rvp
  • 使用这么多,我们无法重现错误。父组件的合成事件很少,而且太大,无法在此处添加。我会尽量减少代码并在这里编辑。

标签: javascript reactjs material-ui dom-events


【解决方案1】:

由于您正在向函数传递参数,因此请尝试在 onChange 事件中将其转换为箭头函数

<Checkbox
              checked={this.state.checked}
              onChange={() => this.handleChange('checked')}
              value={user.id}
              color="primary"
            />

【讨论】:

  • 不,没有帮助。谢谢
  • this.handleChange('checked') 创建一个处理函数 handleChange = name =&gt; event =&gt; { 而不是处理函数本身。所以虽然这是一个很好的建议,但它不适用于这段代码。
【解决方案2】:

如果您打算更改复选框的值。在您的情况下,您不能传递相同的值 onChange

onChange={(e)=>this.handleChange(e)}

你的句柄改变功能应该是这样的

handleChange =event=> {        
    this.setState(prevState=>{ 
      checked: !prevState.checked
    }, () => {
      if (this.state.checked) {
        this.props.parentMethod1(this.state.checked)
      } else {
        this.props.parentMethod2(this.state.checked)
      }
    });
  };

这将在每个onChange 事件中更改您的值。

【讨论】:

  • 我需要父方法的值。你能通过这个:codesandbox.io/s/y041zknrqv 吗?它可能会解决问题。
  • 当我只在该组件中使用它时它工作正常。您的父组件没有更新,因为您没有将值传递给父组件。请参考链接codesandbox.io/s/00qpz5vnxl
【解决方案3】:

OP 的原始代码框:https://codesandbox.io/s/y041zknrqv

如果上面的代码框正确地展示了你的实际问题,那么你的问题是你搞砸了event.stopPropagationevent.preventDefault

Parent1Parent2 中,您为div 容器提供onClick 事件处理程序,并在两个处理程序上实现event.preventDefaultevent.stopPropagation。因此,当您第一次单击复选框时会发生以下情况:

  • Checkbox接收点击事件并更新状态,导致checkbox = 真。
  • 事件冒泡到Parent2。这里onClick触发了这个组件的函数handleClick
  • handleClick中,event.preventDefault停止浏览器对该事件的默认操作,意味着未来的点击事件不会触发复选框,而event.stopPropagation阻止父组件触发onClick,意味着Parent1立即不会收到任何点击事件。

现在,从第二次点击事件开始,只有Parent2 可以接收和响应。它的孩子和它的父母将不再处理任何事情。你可以在这里看到控制台登录:https://codesandbox.io/s/r75rp285xq

因此,要解决您的问题,请从 Parent2handleClick 中删除 event.preventDefault。如果您还想纠正Parent1 的行为,请从两个组件中删除event.preventDefault,并从Parent2 中删除event.stopPropagation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2019-06-26
    相关资源
    最近更新 更多