如何正确声明箭头函数?

Ant*_*ony 3 reactjs

有什么区别

document.addEventListener("click", (e) => handleClick(e));
Run Code Online (Sandbox Code Playgroud)

document.addEventListener("click", handleClick);
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,我在控制台中看到:

控制台结果

在第二种情况下:

控制台结果

那么为什么有时结果会翻倍呢?

片段:

import React, {useState, useEffect} from 'react'
import TodoList from './TodoList'

export default function App () {

  const [todos, setTodos] = useState([]);
  const [todoTitle, setTodoTitle] = useState("");
  const [changed, setChanged] = useState(false);

  const handleClick = (e) => console.log("click", e.target);

  useEffect(() => {
    const raw = localStorage.getItem("todos") || JSON.stringify([]);
    setTodos(JSON.parse(raw));
  }, []);

  useEffect(() => {
    document.addEventListener("click", (e) => handleClick(e));
    localStorage.setItem("todos", JSON.stringify(todos));
    
    return () => {
      document.removeEventListener("click", (e) => handleClick(e));
    }
  })

  const addTodo = event => {
    if (event.key === "Enter") {
      setTodos([
        ...todos,
        {
          id: Date.now(),
          title: todoTitle,
          completed: false
        }
      ])
      setTodoTitle("");
    }
  }
    return (
      <div className="container">
        <h1>Todo app</h1>
          <div className="input-field">
            <input
              type="text"
              value={todoTitle}
              onChange={e => setTodoTitle(e.target.value)}
              onKeyPress={addTodo}
              />
            <label>Todo name</label>
          </div>
          <TodoList todos={todos} />
          <button onClick = {() => setChanged(!changed)}>button</button>
      </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 8

主要区别在于,在第一种情况下,您是handleClick直接绑定,而在第二种情况下,您是绑定一个调用的“中间”函数handleClick。但可观察到的结果是相同的。

然而,您看到输出双倍的原因是

document.removeEventListener("click", (e) => handleClick(e));
Run Code Online (Sandbox Code Playgroud)

不起作用。仅当您传递与传递给 的相同removeEventListener函数时才可以工作。如果您通过 ,那就没问题,但如果您使用“中间”函数,则不可能,因为您没有保留对该函数的引用。addEventListenerhandleClick

你可以轻松解决这个问题:

useEffect(() => {
  const handler = (e) => handleClick(e)
  //    ^^^^^^^ "remember" the function
  document.addEventListener("click", handler);
  //                                 ^^^^^^^
  localStorage.setItem("todos", JSON.stringify(todos));

  return () => {
    document.removeEventListener("click", handler);
    //                                    ^^^^^^^
  }
})
Run Code Online (Sandbox Code Playgroud)

但实际上没有必要在这里使用额外的功能。这一层间接是没有用的。直接过去就可以了handleClick