0

I am using SPFX to render items from a list in a table that includes a delete button for each row item.

Here is a condensed version of the parent component:

export interface IHelloWorldState {
  spList: any;
}

class HelloWorld extends React.Component<{}, IHelloWorldState>{ 
    constructor(props) {
        super(props);
        this.state = {
          spList: [],
        };
        this.getListData = this.getListData.bind(this);
        this.deleteListItem = this.deleteListItem.bind(this);
    }

    public componentDidMount() {
        this.getListData();
    }

    public getListData() {
        let html: string = '';
        pnp.sp.web.lists.getByTitle("List Name").items.get().then((items: any[]) => {
            this.setState({ spList : items });
        });
    }

    private deleteListItem (id) {
        let list = pnp.sp.web.lists.getByTitle("List Name");
        list.items.getById(id).delete().then(_ => {});
    }

    public render () {
        return (
            <div>
                <HelloWorldList list={this.state.spList} deleteOnClick={this.deleteListItem} />
            </div>
        );
    }
}

And the child parent:

const HelloWorldList = ({list, deleteOnClick}) => {
  return (
    <table>
          <tr>
            <th>Id</th>
            <th>Title</th>
            <th></th>
          </tr>
          {list.map(item =>
            <tr>
              <td>{item.ID}</td>
              <td>{item.Title}</td>
              <td>
                <button onClick={deleteOnClick(item.ID)}>X</button>
              </td>
            </tr>
          )}
    </table>
  );
};

export default HelloWorldList;

For whatever reason, when the table in the child comp renders, it actually executes the onclick event of the delete button for each row, instead of just rendering the button. That means it deletes every item in the list, one-by-one. Very strange. Not sure what I am doing wrong.

1

Found my issue. In the child component HelloWorldList, I changed:

<button onClick={deleteOnClick(item.ID)}>X</button>

with

<button onClick={() => deleteOnClick(item.ID)}/>

Not exactly sure why I had to do that (maybe because typescript?) but now it doesn't execute automatically when the comp renders. I also realized the first example didn't even call the function when you clicked it.

  • If I may be of assistance, the prop onClick expects a callback, deleteOnClick(item.ID) is a call of the function, not the actual address of the method, which explains why it's called each time this code snippets executes and not on click. An analogy to this behavior would be a method's return statement. The first version would return the result of the method, the second one would return the function to call. Hope this helps! – Abner Peter May 22 '18 at 7:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.