【问题标题】:Cannot pass a simplified function to onClick event handler ReactJs无法将简化函数传递给 onClick 事件处理程序 ReactJs
【发布时间】:2023-04-06 15:19:01
【问题描述】:

在我的 React 应用程序中,我有两个组件,主组件和菜单组件。 Main Component 是 Menu 的父组件。 Menu 显示一个项目列表,单击其中一个项目时,它会借助我作为道具传递给 Menu 的函数来更新 Main 的状态。下面是更好理解的代码:

class Main extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dishes: dishes,
            selectedDish: null
        };
        this.selectDish=this.selectDish.bind(this);
      }

      selectDish(dishId){
        this.setState({ selectedDish: dishId});
      }


  render() {
    return (
      <div className="App">
        <Menu dishes={this.state.dishes} onClick={this.selectDish} />
      </div>
    );
  }
}

export default Main;

下面是菜单组件:

class Menu extends Component {

    constructor(props){
        super(props);
        this.selectdish=this.selectdish.bind(this);
    }
    selectdish(dishId){
        return this.props.onClick(dishId);
    }

    render() {
        const menu = this.props.dishes.map((dish) => {
            return (
                <div className="col-12 col-md-5 m-1">
                <Card key={dish.id}
                  onClick={this.selectdish(dish.id)}>
                </Card>
              </div>
            );
        });

    }
}

export default Menu;

我省略了代码中一些不相关的部分。 所以工作流程应该是,当我们点击菜单呈现的菜品之一时,菜品的 id 应该传回 Main 并更新状态变量 ``selectedDish```,如方法 selectDish 所示。

但在浏览器控制台中,我收到错误 Cannot update during existing state transition。 奇怪的是,如果我不传递任何菜品 ID 并将 selectedDish 设置为 1 之类的固定值,一切正常。

请帮我确定我的事件处理程序是否有任何问题,因为这是唯一似乎包含错误的部分。

谢谢!

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您没有将卡片的onClick 传递给函数,但您已经使用this.selectdish(dish.id) 调用了该函数。这将在渲染时启动流程,而不是在点击时。

    这里有三个选项。

    您可以将其包装在像这样的附加函数中:onClick={() =&gt; {this.selectdish(dish.id)}}&gt;。这样,您将一个函数传递给 onClick,这是必需的,而不是执行它。

    或者你让selectdish返回一个这样的函数:

     selectdish(dishId){
        return () => {this.props.onClick(dishId)};
    }
    

    或者你给卡片添加一个名字,然后从点击事件中访问元素的名字:

    class Menu extends Component {
    
    constructor(props){
        super(props);
        this.selectdish=this.selectdish.bind(this);
    }
    selectdish(event){
        return this.props.onClick(event.target.name);
    }
    
    render() {
        const menu = this.props.dishes.map((dish) => {
            return (
                <div className="col-12 col-md-5 m-1">
                <Card key={dish.id}
                  name={dish.id}
                  onClick={this.selectdish}> // this is now the function without calling it
                </Card>
              </div>
            );
        });
    
    }
    }
    
    export default Menu;
    

    【讨论】:

    • 感谢您的回答,但是为什么您说该函数将在渲染期间执行。在纯 javascript 中,我们本身就是这样做的。
    • this.selectdish(dish.id) 会执行一个函数吗?所以 onClick={this.selectdish(dish.id)}> 也会在 render 上执行函数
    • 为什么在渲染时,应该在点击时执行。我无法得到那部分。
    • 还有一件事,为什么我们甚至在 selectdish 中返回函数。为什么我们不能只调用函数?
    • 因为每当你写 function() 时,你都会执行它。而你正在这样做。您需要将其包装在一个附加函数中并将该函数传递给 onClick 以在单击时执行,
    【解决方案2】:

    你的代码有问题:

    1. 属性key 必须在根&lt;div&gt; 中定义
    2. Menu 组件中的渲染方法不返回任何内容

    -

    class Menu extends React.Component {
      constructor(props) {
        super(props);
        this.selectdish = this.selectdish.bind(this);
      }
      selectdish(dishId) {
        return this.props.onClick(dishId);
      }
    
      render() {
        return this.props.dishes.map(dish => {
          return (
            <div className="col-12 col-md-5 m-1" key={dish.id}>
              <div onClick={() => this.selectdish(dish.id)}>{dish.id}</div>
            </div>
          );
        });
      }
    }
    

    查看我修复此问题的游乐场:

    https://codesandbox.io/s/react-playground-ib6pr?file=/index.js

    【讨论】:

    • 我已经删除了那部分。
    猜你喜欢
    • 2016-06-23
    • 2018-09-26
    • 1970-01-01
    • 2012-08-30
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多