【问题标题】:Can we pass event name as props in react?我们可以在反应中将事件名称作为道具传递吗?
【发布时间】:2017-05-22 05:40:52
【问题描述】:

您好,我是新手,我正在尝试创建一个组件,我们可以在其中将事件名称(onclick、onChange 等)作为道具传递。所以组件也可以以事件的方式进行定制。有可能吗?

<Input  {this.props.eventName} = {this.props.name} />

这是我想做的。有可能吗?

【问题讨论】:

  • 这没有多大意义。有可能,但为什么呢?
  • 我想从父组件发送事件名称,以便组件可以使用传递的事件。假设我发送 eventName = onClick。当我在不同的地方使用相同的组件时,所以想要 onChnage 事件。所以很简单我可以通过 eventName = onChange.
  • 为什么不直接使用onClick={...}onChange={...}?或者将 props 传播到子组件:{...this.props}?

标签: reactjs ecmascript-6 react-dom


【解决方案1】:

你想实现类似的东西吗-

一个问题是您必须只将受支持的事件传递给元素类型。 例如 button onClickbutton 支持的其他事件。

class Parent extends React.Component {
  
  render() {
    return(
       <ChildComponent
        evtName = 'onClick' 
        evtHandler={ () => { console.log("event called!");}}
       />
    )
  }
}

class ChildComponent extends React.Component {
  render() {
     return React.createElement(
        'button',
        { [this.props.evtName] : this.props.evtHandler },
        'Click me'
      );  }
}


ReactDOM.render(
  <Parent />,
  document.getElementById('root')
);
<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="root"></div>

【讨论】:

  • 就是这样做的,但是没有意义。是吗?
  • @loelsonk 你是对的。但这就是OP想要的。这只是一种 hacky 方式。
【解决方案2】:

如果我理解正确,只需将 event 传递给 handler 作为道具。我没有看到仅考虑事件名称的用例。

请参阅下面的示例,使用不同的事件重用相同的元素。

class Input extends React.Component {
  render(){
    const {} = this.props;
    return (
      <input {...this.props} />
    );
  }
}

class Test extends React.Component {
  render(){
    return (
      <div>
        <Input name="onClick" onClick={(e) => console.log(e.target.name)}/>
        <Input name="onChange" onChange={(e) => console.log(e.target.name)}/>
      </div>
    );
  }
}

ReactDOM.render(<Test />, document.getElementById("root"));
<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="root"></div>

【讨论】:

    【解决方案3】:

    以下是如何将 event 从父组件传递给子组件的示例 - 通过在父组件中生成结果。

    class Parent extends Component {
      //constructor, other methods, etc...
    
      // We call our event update
      update(stuff) {
        console.log(stuff);
      }
    }
    

    我们在 ParentComponent 的渲染方法中传递了一个 ChildComponent 和 props onClick(你可以随意命名)。

    <ChildComponent
      onClick={this.update.bind(this)}
    />
    

    现在,子组件。要访问我们的道具onClick,我们只需使用this.props.onClick。我们的参数只是hello,您可以传递任意数量的参数。

    <button onClick={ (e) => this.props.onClick('hello') }>
      Action
    </button>
    

    这是工作示例:

    class Parent extends React.Component {
      
      update(stuff) {
        console.log(e, stuff);
      }
      
      render() {
        return(
           <ChildComponent
            onClick={this.update.bind(this)} />
        )
      }
    }
    
    class ChildComponent extends React.Component {
    
      render() {
        return(
          <div>
          <button onClick={ (e) => this.props.onClick('hello') }> Action</button>
          </div> 
        )
      }
    }
    
    
    ReactDOM.render(
      <Parent />,
      document.getElementById('root')
    );
    <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="root"></div>

    【讨论】:

    • 这里您传递了必须在 onClick 事件上调用的方法。很好,但是我想让事件动态化。像这里如果你想改变事件到 onChange 意味着你必须改变子组件。但我不想这样做,我只想将它作为道具传递。希望我表达了自己的观点。
    • @suyesh 你把它作为道具传递。 &lt;ChildComponent onClick={that's it}。您可以通过相同的道具this.props.onClick 访问它。您可以随意调用它:&lt;ChildComponent myAction={/* function to call */} 可以通过 this.props.myAction 访问该道具。
    • 好的,我明白你的意思了。在我看来这是不可能的,因为你怎么知道你应该在ChildComponent中调用什么道具名称,你可以将它作为另一个道具传递,但你仍然需要一些硬编码的信息。我认为你遇到了经典的@987654321 @。你应该尽可能简单,以后维护起来会更容易。
    猜你喜欢
    • 2021-11-01
    • 2017-01-31
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2020-09-14
    • 2017-05-09
    • 2018-10-11
    相关资源
    最近更新 更多