何时使用 onclick ={ myfunction()} vs onclick={() => (myfunction())}

When to use onclick ={ myfuntion()} vs onclick={() => (myfunction())}

为什么在使用 onClick= {(randomCard()} 时在 randomCard 函数中未定义 id 并在使用 onClick = {() => (randomCard())}

时定义
function Home() {
    const [cardlist, setCardList] = useState([]);
    const navigate = useNavigate()
    
    function randomCard() {
        const index = Math.floor(Math.random() * cardlist.length);
        const id = cardlist[index].id;
        navigate(`/cards/${id}`)
    }  

    useEffect(() => {
        async function fetchData() {
            const res = await axios.get('https://db.ygoprodeck.com/api/v7/cardinfo.php');
            const results = res.data;
            setCardList(results.data);
            console.log(cardlist);
        }
        fetchData();
    }, [])

    return (
        <div className='home'>
            <h1>Welcome to the Yu-Gi-Oh Database</h1>
            <p>Choose Option</p>
            <div className="options">
                <ul>
                    <li><a href='/allcards'>Show All Cards</a></li>
                    <li><a href='/'>Search Card</a></li>                    
                    <li><a href='' onClick={() => (randomCard())}>Random Card</a></li>                    
                </ul>
               
            </div>
        </div>
  )
}

人们只会使用像

这样的东西
onClick={randomCard()}

当那个函数returns一个函数。这种情况并不少见,例如:

const makeHandleClick = (id) => () => {
  setClickedId(id);
};
onclick={makeHandleClick(id))

但是当您实际上只想在单击元素时 运行 函数时使用 onClick={randomCard()} 是一个常见的错误 - 在这种情况下,将立即 运行 函数,呈现时,而不是单击时(通常会导致太多 re-renders 和错误)。

使用

onClick={randomCard}

当您希望函数 运行 在单击元素时而不是在呈现元素时。

以上通常等同于

onClick={() => randomCard()}

您问题的关键答案是了解以下两者之间的区别:

  • 正在调用 onClick={() => (randomCard())} 这是应要求调用
  • 执行onClick= {randomCard()}这就是立即执行

我建议你研究一下,这样你会更清楚,但简而言之,onClick={() => (randomCard())} 当你点击它时调用它,onClick= {randomCard()} 当文件加载时调用它.

当您使用“执行”时,您的数据将不会被提取,并且该函数将在 setCardList 赋值给 cardList 之前被调用。 但是当您使用“调用”时,您的数据已经被提取,并且 cardList 保存着一个数据数组。

希望我没有把你弄糊涂,稍微研究一下你就会明白,它非常简单,只需要了解渲染组件的流程。

在 React 中,onClick 的值必须是一个 回调 returns something ( void ) :

onClick={() => { 
    console.log('clicked')}
}

因此,当将 functions() 作为值传递给 onClick 时,它会在组件呈现时 运行。 在您的情况下,onClick={randomCard()} 将在数据获取发生之前 运行,这意味着卡的 idundefined。 下面的示例代码将在渲染时登录到控制台,而不是在单击时登录:

// Outputs console log on render only
function doSomething() {
    console.log('executed without click event')
}

return(
    <button
      type="button"
      onClick={doSomething()}
    >
)

如果您使用的是 Typescript,您将在输入时看到错误:

Type 'void' is not assignable to type 'MouseEventHandler<HTMLButtonElement> | undefined'.这意味着我们正在执行 JS (void) 而不是传递回调 (MouseEventHandler) 作为值.

与处理 HTML DOM 事件不同,您可以在其中将任何 JS 代码作为字符串传递给 onclick,它会在单击元素时触发一个函数。例如:

// All work
<button onclick="document.getElementById('demo').innerHTML=1">Click me</button>
<button onclick="console.log('Hi')">Click me</button>
<button onclick="alert('Hi')">Click me</button>
<button onclick="greet()">Click me</button>

<p id="demo"></p>

function greet() {
    document.getElementById("demo").innerHTML = "Hello World";
}