先来看一段代码
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const GrandSon = () => {
const [n, setN] = React.useState(0);
return (
<div className="grand-son">
孙子,n:{n}
<button onClick={() => setN(n + 1)}>+1</button>
</div>
);
};
class Son extends React.Component {
constructor() {
super();
this.state = { n: 0 };
}
add() {
this.setState({ n: this.state.n + 1 });
}
render() {
return (
<div className="son">
我是儿子,n:{this.state.n}
<button onClick={() => this.add()}>+1</button>
<GrandSon />
</div>
);
}
}
function App() {
return (
<div className="app">
<p>我是爸爸</p>
<Son />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
为什么函数组件和类组件的事件绑定都要传一个函数呢?想这个问题之前,我们可以再看一个点,为什么react中的类名的设置要用className
而不是正常的html属性class
。
原因是react的所有dom操作都是在js中完成的,我们看到的标签,只是React为了方便书写而存在的,真实的代码都会被babel.js
自动转换为 React.createElement
的方式去创建真实的html标签,那么js中操作类名的属性是什么?是className
,而事件的绑定呢?是一个函数。
原始的js事件绑定的方式:
var div = document.querySelector('div')
div.onClick = () => {}
div.onClick = function() {}
看了上述代码,就能明白为什么React的jsx中要那么写事件绑定了吧?
总结: React本身就是一个js框架,它就是封装了js且方便了代码的编写。很多东西,React还是依然沿用了js的东西。至于为什么jsx中事件绑定的代码用大括号包裹,那是因为jsx中的js代码都要用大括号包裹才行。
如果对这个还是不够理解,那就拷贝下面的代码到babelOnline上,看是怎么被转换的就一切了然了。
// function App(){
// cosnt [n,setN] = React.useState(0)
// return (
// <div>n:{n}
// <button onClick={() => setN(n + 1)}>+1</button>
// </div>
// )
// }
// <App />
class Son extends React.Component {
constructor() {
super()
this.state = {n: 0}
}
render() {
return (
<div>
n:{this.state.n}
<button onClick={() => this.setState({n: this.state.n + 1})}>+1</button>
</div>
)
}
}
<Son />