Binding buttons in SPFx
When writing a react based SPFx application one has to make a note that ES6 React.Component doesn’t auto bind methods to itself.
Hence it’s required to manually bind and the following are two ways to do it.
Method 1
onClick={this.addButtonClicked.bind(this)}
import * as React from 'react'; import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack'; import { ActionButton } from 'office-ui-fabric-react/lib/Button'; import { IIconProps } from 'office-ui-fabric-react/'; import { ITestComponentState } from './ITestComponentState'; import { ITestComponentProps } from './ITestComponentProps'; //Stack related styles const outerStackTokens = { childrenGap: 50 }; const addFriendIcon: IIconProps = { iconName: 'Add' }; let outerStackStyles: Partial<IStackStyles> = {}; let innerStackColumnProps: Partial<IStackProps> = {}; export default class TestComponent extends React.Component<ITestComponentProps, ITestComponentState> { constructor(props: ITestComponentProps) { super(props); this.state = { items: [] }; } public render(): React.ReactElement<{}> { return ( <div> <Stack horizontal tokens={outerStackTokens} styles={outerStackStyles}> <Stack verticalAlign="start" {...innerStackColumnProps}> <Stack.Item align="start" > <ActionButton iconProps={addFriendIcon} onClick={this.addButtonClicked.bind(this)} allowDisabledFocus disabled={this.state.sortItems.length >= 10 ? true : false} >Add Item</ActionButton> </Stack.Item> </Stack> </Stack> </div> ); } private addButtonClicked(event?: React.MouseEvent<HTMLButtonElement>) { let itemsOnAdd = this.state.items; let itemTitle = "Item " + (this.state.items.length + 1); itemsOnAdd.push({ title: itemTitle }); this.setState({ items: itemsOnAdd }); } }
Method 2
this.addButtonClicked = this.addButtonClicked.bind(this);
import * as React from 'react'; import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack'; import { ActionButton } from 'office-ui-fabric-react/lib/Button'; import { IIconProps } from 'office-ui-fabric-react/'; import { ITestComponentState } from './ITestComponentState'; import { ITestComponentProps } from './ITestComponentProps'; //Stack related styles const outerStackTokens = { childrenGap: 50 }; const addFriendIcon: IIconProps = { iconName: 'Add' }; let outerStackStyles: Partial<IStackStyles> = {}; let innerStackColumnProps: Partial<IStackProps> = {}; export default class TestComponent extends React.Component<ITestComponentProps, ITestComponentState> { constructor(props: ITestComponentProps) { super(props); this.state = { items: [] }; this.addButtonClicked = this.addButtonClicked.bind(this); } public render(): React.ReactElement<{}> { return ( <div> <Stack horizontal tokens={outerStackTokens} styles={outerStackStyles}> <Stack verticalAlign="start" {...innerStackColumnProps}> <Stack.Item align="start" > <ActionButton iconProps={addFriendIcon} onClick={this.addButtonClicked} allowDisabledFocus disabled={this.state.sortItems.length >= 10 ? true : false} >Add Item</ActionButton> </Stack.Item> </Stack> </Stack> </div> ); } private addButtonClicked(event?: React.MouseEvent<HTMLButtonElement>) { let itemsOnAdd = this.state.items; let itemTitle = "Item " + (this.state.items.length + 1); itemsOnAdd.push({ title: itemTitle }); this.setState({ items: itemsOnAdd }); } }