【问题标题】:Passing an additional parameter with an onChange event使用 onChange 事件传递附加参数
【发布时间】:2017-12-08 14:35:24
【问题描述】:

我想做的事:

我正在尝试将字符串从子组件传递给父组件的 handleChange 函数。

目前有效:

我有一个 React JS 父类,方法如下:

handleChange(event) {

    console.log(event.target.value);
}

在渲染函数中我有以下内容:

<Child handleChange={this.handleChange.bind(this)} />

在我的子类中:

<fieldset onChange={this.props.handleChange}>
    <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
    <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
    <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
</fieldset>

这很好用。

我想做什么:

我正在尝试将section 参数添加到handleChange 函数中,如下所示:

handleChange(section, event) {
    console.log(section);
    console.log(event.target.value);
}

在 Child 类中我有:

<fieldset onChange={this.props.handleChange("tags")}>
    <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
    <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
    <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
</fieldset>

我现在得到错误:

Uncaught TypeError: Cannot read property 'target' of undefined

在我的第二个 console.log 语句中抛出了这个错误。

我做错了什么?

另外,我正在考虑将section 参数设为可选。如果是这样,有没有简单的方法可以做到这一点?如果事件参数需要放在最后,似乎不可能。

【问题讨论】:

  • @ShubhamKhatri 这不是这个问题的重复,因为我试图将参数从子类传递给父类。因此,我无法在 元素的 onChange 属性中指定变量,因为它看不到子组件内部的变量。
  • 好的明白了,我将删除关闭投票。
  • 请将解决方案发布为答案,而不是更新您的问题。这是为了帮助未来的访客并避免混淆。谢谢。

标签: reactjs onchange


【解决方案1】:

当你写这篇文章时:

<fieldset onChange={this.props.handleChange("tags")}>

handleChange 将在触发渲染后立即调用。

相反,这样做:

<fieldset onChange={(e) => this.props.handleChange("tags", e)}>

现在handleChange 将在onChange 处理程序被调用时被调用。

【讨论】:

  • 我可能弄错了,但是使用箭头函数(或 .bind)作为道具是不好的做法,并且可能会影响性能。在这里解释:medium.freecodecamp.org/…
【解决方案2】:

你可以这样做:

<fieldset onChange={(e) => this.props.handleChange("tags", e)}>
    <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
    <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
    <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
</fieldset>

【讨论】:

    【解决方案3】:

    为了将参数从子组件传递给父组件,您可以将参数传递给箭头函数。

    handleChange(event, section) {
        console.log(section);
        console.log(event.target.value);
    }
    <Child handleChange={(e, val) => this.handleChange(e, val)} />
    
    <fieldset onChange={(e) => this.props.handleChange(e, "tags")}>
        <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
        <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
        <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
    </fieldset>
    

    示例 sn-p

    class App extends React.Component {
      handleChange(e, val) {
        console.log(e.target.value, val);
      }
      render() {
        return(
          <Child handleChange={(e,val) => this.handleChange(e, val)}/>
        )
      }
    }
    
    class Child extends React.Component {
      
      render() {
        return(
          <input type="text" onChange={(e) => this.props.handleChange(e, 'tab')}/>
        )
      }
    }
    
    ReactDOM.render(<App/>, 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>

    【讨论】:

    • 元素中使用箭头功能是否比我已经拥有的有好处?
    【解决方案4】:

    作为 OP,我最初将其发布为对我的问题的跟进,但它已被删除,我被告知将其发布为答案,所以这里是:

    根据 Ritesh Bansal 的回答,我了解到以下内容:

    以下行不起作用,因为在函数名称后使用括号时,会立即调用该函数,而不是等待更改发生:

    <fieldset onChange={this.props.handleChange("tags")}>
    

    上面的行不通,这样的函数也行不通:

    <fieldset onChange={this.props.handleChange()}>
    

    上面的代码也会在第一次渲染时立即被调用。

    有两种解决方案:

    不太好的方法:

    <fieldset onChange={this.props.handleChange.bind(this, "tags")}>
    

    更好的方法:

    <fieldset onChange={(evt) => this.props.handleChange("tags", evt)}>
    

    问题现在解决了。谢谢大家!

    更新:

    我还研究了 Shubham Khatri 的建议,将子元素更改为:

    <Child handleChange={(e,val) => this.handleChange(e, val)}/>
    

    我没有意识到在渲染函数中使用bind,每次调用渲染都会创建一个新的函数实例。因此,我既可以使用 Shubham Khatri 的方法,也可以在构造函数中绑定这些方法。

    【讨论】:

    • ,是最好的方法,当考虑到优化时,只是你的绑定应该在构造函数中功能
    • Doing (e, val) => this.handleChange(e, val) 和我的回答一样。在这两种情况下,一个函数都会返回另一个函数。
    【解决方案5】:

    在你的handle事件中使用双箭头函数,使用箭头函数时不需要绑定:

    handleChange = tags => (event) => {
        console.log(tags);
        console.log(event.target.value);
    }
    

    在孩子身上:

    <fieldset onChange={this.props.handleChange("tags")}>
        <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
        <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
        <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
    </fieldset>
    

    【讨论】:

    • 注意这目前需要 babel 插件“transform-class-properties”
    【解决方案6】:

    没有在每个 render() 上定义匿名函数

    这里的大多数答案都推荐在 render() 中定义的匿名函数,正如 Davidicus 指出的那样,不推荐使用:https://medium.freecodecamp.org/why-arrow-functions-and-bind-in-reacts-render-are-problematic-f1c08b060e36

    弗朗索瓦的回答避免了这个问题,但正如 Vael Victus 指出的那样,这需要transform-class-properties

    但是,他所做的只是定义一个定义函数的函数,否则您可以这样做:

    constructor(props) {
      super(props);
      this.handleChange = (yourSpecialParam) => (event) => this.handleChange(yourSpecialParam).bind(this)
    }
    
    render() {
      return <button onClick={this.handleChange(1234)} >Click Me</button>
    }
    

    【讨论】:

      【解决方案7】:
      const handleChange = (tags) => (event) => {
      // console.log(tags);
      // console.log(event.target.value);
      };
      
      <input
            type="text"
            name="name"
            placeholder="Name"
            value={input.Iname}
            onChange={handleChange("Iname")}
          />
      

      【讨论】:

        猜你喜欢
        • 2011-07-10
        • 2020-12-23
        • 2019-08-09
        • 2014-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 2013-01-12
        相关资源
        最近更新 更多