何时使用 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()}
将在数据获取发生之前 运行,这意味着卡的 id
是 undefined
。
下面的示例代码将在渲染时登录到控制台,而不是在单击时登录:
// 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";
}
为什么在使用 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()}
将在数据获取发生之前 运行,这意味着卡的 id
是 undefined
。
下面的示例代码将在渲染时登录到控制台,而不是在单击时登录:
// 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";
}