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
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];
};
}
onDelete(e) {
const id = e.target.dataset.id;
}
<DropdownItem data-id={item.id} onClick={this.onDelete}><i className="fa fa-trash" /> Remove</DropdownItem>
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#.
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>
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 });
};
}