'React - ES6 way' of binding click handlers with parameters

后端 未结 5 2085
暗喜
暗喜 2021-02-09 12:52

I\'ve read a bunch of articles about the use of () => {} syntax, binding in the constructor, binding in the props etc.. but from what I understand, binding

相关标签:
5条回答
  • 2021-02-09 13:06

    Syntactically, I much prefer arrow functions to binding (especially since only arrow functions facilitate passing extra arguments to event handlers). Understanding the performance penalty associated with arrow functions, I created a utility function that accepts arrow function definitions which will be cached for the lifetime of a component:

    utils.js

    export function createLambdaCache() {
      const result = {};
      return (key, lambda) => {
        if (!(key in result)) {
          result[key] = lambda;
        }
        return result[key];
      };
    }
    

    component.js

    class MyComponent extends React.Component {
      render() {
        return (
          ...  
          // below 'btnEvent' string is used as a key to cache the event reference for subsequent renders
          <button onClick={this.bindWithArgs('btnEvent', evt => this.clickHander(id, evt))} />
          ...
        );
      }
      clickHandler(id, evt) {
        console.log(id, evt);
      }
      bindWithArgs = createLambdaCache();
    }
    

    typescript version of above createLambdaCache:

    type evtHandler<E> = (evt: E) => void;
    export function createLambdaCache<T = any>() {
      const result: {[key in keyof T]: evtHandler<any>} = {} as any;
      return <E>(key: keyof T, lambda: evtHandler<E>) => {
        if (!(key in result)) {
          result[key] = lambda;
        }
        return <evtHandler<E>>result[key];
      };
    }
    
    0 讨论(0)
  • 2021-02-09 13:18
    onDelete(e) {
        const id = e.target.dataset.id;
    }
    
    <DropdownItem data-id={item.id} onClick={this.onDelete}><i className="fa fa-trash" /> Remove</DropdownItem>
    
    0 讨论(0)
  • 2021-02-09 13:20

    For your <li onClick={this.handleClick.bind(this, item.id)} />{item.name}</li>

    this typically means you need another layer of abstraction IE a new react component that returns the same element but you can pass in the onClick as a prop as well as item id as a prop. Then in that component you would call this.props.onClick(this.props.id) or however you format the data.

    this article draws out all the differences between each way of binding instance methods as well as how each impacts performance https://medium.com/@housecor/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56#.

    0 讨论(0)
  • 2021-02-09 13:24

    If passing a parameter then you must bind in the render function and not in the constructor. This can be done using the bind or an arrow function.

    <li onClick={this.handleClick.bind(this, item.id)} />{item.name}</li>
    

    or

    <li onClick={() => this.handleClick(item.id)} />{item.name}</li>
    
    0 讨论(0)
  • 2021-02-09 13:29

    Does this work? (Using TypeScript)

    <Input type="password" onChange={this.onPasswordInputChange('primary')} />;
    <Input type="password" onChange={this.onPasswordInputChange('secondary')} />;
    
    
    interface IOnPasswordInputChange {
      (value: string): void;
    }
    
    private onPasswordInputChange = (type: string): IOnPasswordInputChange => {
      return (value: string) => {
        this.setState({ [type]: value });
      };
    }
    
    0 讨论(0)
提交回复
热议问题