目录
一、函数之 JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test</title>
</head>
<body>
<button id="btn1">click one</button>
<button id="btn2">click two</button>
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
btn1.onclick = fn
btn2.onclick = fn()
function fn(){
console.log(333);
return (function f(){
console.log("hello world")
}).bind(this)
}
</script>
<body>
<html>
执行上述代码后:
第一个 button 没有任何打印,当点击该按钮时,打印:333;
第二个 button 打印 333,当点击该按钮时,继续打印:hello world
二、函数之 Vue
<template>
<div>
<button @click="handleClick">Click Me</button>
<button @click="handleClick()">Click Me</button>
</div>
</template>
<script>
export default {
methods: {
handleClick () {
console.log(333)
return () => {
console.log("hello world")
}
}
}
}
</script>
执行上述代码后,没有任何打印,当点击这两个button时,结果都一样:hello world。
三、函数之 React+JSX
import { Component } from 'react'
class Test extends Component {
const handlerClick = () => {
console.log(333)
return () => {
console.log("hello world");
}
}
render () {
return (
this.state.list.map((item, idx) => {
return (
<button onClick="this.handlerClick">click me</button>
<button onClick="this.handlerClick()">click me</button>
);
})
);
}
}
export default Test;
执行上述代码后:
第一个 button 没有任何打印,当点击该按钮时,打印:333;
第二个 button 打印 333,当点击该按钮时,继续打印:hello world
【总结】综上所述:
JavaScript 和 React+JSX 里的函数执行结果一致:
- 直接写一个函数名,执行函数体内 return 之前的代码;
- 在函数名后写()调用函数,先执行函数体内 return 之前的代码,然后,执行 return 后的代码。
Vue 里的函数:
- 直接写一个函数名 或者 在函数名后写()调用函数,都是只执行 return 后的代码。
四、一个场景
vue
<template>
<div>
<ul v-for="(item, idx) in list" :key="idx">
<li><input @change="handleChange(...arguments, idx)" />{item}</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return {
list: [1,2,3,4,5,6]
}
},
methods: {
change(e, id){
console.log(e.target.value, id)
}
}
}
</script>
上述代码正常执行。
react
const Test = () => {
const list = [1,2,3,4,5,6]
const handleChange = (c) => {
console.log(c.target.value)
}
return (
<React.Fragments>
{list.length && list.map((item, idx)=>{
return (
<ul key={idx}>
<li><input onChange={handleChange}/>{item}</li>
</ul>
)
})}
</React.Fragments>
)
}
上述代码可以正常执行。
const Test = () => {
const list = [1,2,3,4,5,6]
const handleChange = (e, id) => {
console.log(e.target.value, id)
}
return (
<React.Fragments>
{list.length && list.map((item, idx)=>{
return (
<ul key={idx}>
<li><input onChange={handleChange(...arguments, idx)}/>{item}</li>
</ul>
)
})}
</React.Fragments>
)
}
上述代码报错。
五、react 中的 onClick 事件
import { useState } from 'react'
const Test = () => {
const [showHi, setShowHi] = useState(false);
const list = [{
id: 0,
name: "不理睬",
},{
id: 1,
name: "打招呼",
}]
const handleClick = (item) => {
item.id ? setShowHi(true) : setShowHi(false);
}
return (
<ul>
{list.map((item) => {
return (
<li key={item.id}>
<button onClick={handleClick(item)}>
{item.name}
</button>
</li>
)
})}
{showHi ? (
<span>🙋♂️</span>
) : ("")}
</ul>
)
}
export default Test;
上述代码运行会报错,造成无限循环:Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
如何解决这个问题呢?有两种方式:
方式一:
import { useState } from 'react'
const Test = () => {
const [showHi, setShowHi] = useState(false);
const list = [{
id: 0,
name: "不理睬",
},{
id: 1,
name: "打招呼",
}]
const handleClick = (item) => {
item.id ? setShowHi(true) : setShowHi(false);
}
return (
<ul>
{list.map((item) => {
return (
<li key={item.id}>
<button onClick={() => { handleClick(item) }}>
{item.name}
</button>
</li>
)
})}
{showHi ? (
<span>🙋♂️</span>
) : ("")}
</ul>
)
}
export default Test;
方式二:
import { useState } from 'react'
const Test = () => {
const [showHi, setShowHi] = useState(false);
const list = [{
id: 0,
name: "不理睬",
},{
id: 1,
name: "打招呼",
}]
const handleClick = (item) => {
return () => {
item.id ? setShowHi(true) : setShowHi(false);
}
}
return (
<ul>
{list.map((item) => {
return (
<li key={item.id}>
<button onClick={handleClick(item)}>
{item.name}
</button>
</li>
)
})}
{showHi ? (
<span>🙋♂️</span>
) : ("")}
</ul>
)
}
export default Test;