0

I code a page in react, it interacts with a small API code with express by me and I created a button when I click on it it deletes a message but when I don't click the function is still executed... my code:

delete(id){
    for (let i = 0; i<1; i++) {
        axios.delete(`http://localhost:8080/messages/${id}`)
            .then(res => {
                console.log(res);
                console.log(res.data);
            })
    }
}

render() {
    return (
        <div>
            <ul>
                {<button type="submit" onClick={this.delete(messageId)}>suprimmer</button></li>}
            </ul>
        </div>
    )
}

}

B0tm4n
  • 15
  • 10
  • you can use `onClick={() => this.delete(messageId)}`, otherwise your function will run when your JSX is initially returned from`render()`. You also don't need a for loop in your `delete()` method if you're only doing 1 iteration. – Nick Parsons Aug 08 '21 at 12:40

2 Answers2

0

Does this work:

<button type="submit" onClick={() => this.delete(messageId)}>suprimmer</button>

When you do it as you did in your version, you are actually calling the function.

starikcetin
  • 1,391
  • 1
  • 16
  • 24
0

onClick receives value as its function to trigger/call/run when user "click" on it. But in your code, you trigger/call/run function this.delete() during compile phase (compiler read Button onClick={this.delete(id)}>Delete Button</button> and called this.delete(id) immediately and use the result of it as onClick's value(delete function return nothing it means {return undefined}, so the final result is ` ).

So the result is:

  • Everytime the component loaded, it will call delete instantly. And onClick value now is undefined and it makes onClick won't work as expected.

For more details I'll give an example below:

const DeleteButton =({id})=> {
  const delete = (id)=> {
      return api.deleteItem(id)
  }

  return <Button onClick={delete(id)}>Delete Button</button>

}

So, when I use the component above:

<Container>
  <Content value={item}/>
  <DeleteButton id={item.id}/>
</Container>

it will automatically delete the item you've loaded, because while render DeleteButton it called delete(id) already.

So, how to fix it? - there are many solutions for it, but ultimately it have to give the type of value of onClick is a function:

#1 I bet noone use this, but I think it is more useful to describe my idea.

const DeleteButton =({id})=> {
  const delete = (id)=> {
      return function() {
       api.deleteItem(id)
      }
  }

  //delete(id) called and it returns an anonymous function that receive `id` and called it when onClick trigger
  return <Button onClick={delete(id)}>Delete Button</button>

}

#2

const DeleteButton =({id})=> {
  const delete = (id)=> {
     return  api.deleteItem(id)
  }

  return <Button onClick={(id)=>delete(item.id)}>Delete Button</button>
//or use bind : bind is return a function that wrapped parameter into
  return <Button onClick={delete.bind(id)}>Delete Button</button> 

}
Kai
  • 3,104
  • 2
  • 19
  • 30