元素与组件
元素 : const div = React.createElement('div',...)
组件: const Div = ()=> React.createElement('div',...)
元素的d尽量小写,组件的D尽量大写
函数组件与类组件
- 函数组件:
const Welcome = (props)=> {
return (
<section>
<div>
hi, {props.name}
</div>
</section>
);
}
<Welcome name='Tom' />
- 类组件
class Welcome extends React.Component {
constructor() {
super();
}
render() {
return (
<section>
<div>
hi, {this.props.name}
</div>
</section>
)
}
}
<Welcome name='Tom' />
在react中,无论我们时写html标签<div></div> 还是写组件 <Welcome /> 都会被翻译成React.createElement('div') / React.createElement(Welcome) 我们可以通过babel online自己尝试以下。
react的外部数据
- 传入外部数据
在reat中,我们可以直接在组件标签上添加其外部数据
//传字符串
<Welcome name='Tom' />
//传变量
<Welcome number={0} />
- 引入外部数据
//在函数组件中
{props.name}
//在类组件中
{this.props.name}
react的内部数据
- 在类组件中
class App extends React.Component {
constructor() {
super();
this.state = {n: 0}
//在constructor中声明n
}
addN = () => {
this.setState((state) => {
//使用this.setState修改n
const n = state.n + 1
return {n}
})
}
render() {
return (
<section>
<div>
{this.state.n}
</div>
<hr/>
<button onClick={this.addN}>+1</button>
</section>
)
}
}
这里的setState是异步操作
- 在函数组件中
const App = () => {
const [n,setN]=React.useState(0)
//使用析构赋值,声明n和setN
return (
<section>
{n}
<hr/>
<button onClick={()=>{setN(n + 1)}}>+1</button>
//使用setN 修改n
</section>
)
}
state中复杂数据的问题
在上面的state中只有一个数据,所以我们无论如何set都不会有问题,但当state中有多个数据时,问题就出现了。
- 类组件
在类组件中,setState会帮你自动合并第一层属性(eg:当有m n 两个数据时,修改其中一个不会影响另一个)
但是如果你修改了其中第二层的一个数据,那么react不会帮你保留其他数据。(如果你想保留,可以使用 ...this.state.xxx)
changeUser=()=>{
this.setState((state)=>{
const user = {...this.state.user,name: 'jack'}
return {user}
})
}
- 函数组件
在函数组件中,react不会帮你合并任何值
const App = ()=>{
const [state,setState] = React.useState({n:0,m:0})
return(
<section>
n : {state.n}
<hr/>
<button onClick={()=>{setState({...state,n: state.n + 1})}}>n + 1</button>
<hr/>
m:{state.m}
<hr/>
<button onClick={()=>{setState({...state,m:state.m+1})}}>m + 1</button>
</section>
)
}
我们可以通过展开操作符来解决这一问题,或者,在声明m n 时,分开声明。
事件绑定(类组件)
在react中,我们有两种声明方法的方式。
//第一种
class App extends React.Component {
constructor() {
super();
this.state = {n: 0}
}
addN() {
this.setState(state => {
const n = state.n + 1
return {n}
})
}
render() {
return (
<section>
n : {this.state.n}
<button onClick={() => {
this.addN()
}}> + 1
</button>
</section>
)
}
}
此时的addN是在原型链上的
而button的原理是 button.onClick.call(null)的,所以如果不使用箭头函数,那么this就会指向window。
class App extends React.Component {
constructor() {
super();
this.state = {n: 0}
}
addN = () => {
this.setState(state => {
const n = state.n + 1
return {n}
})
}
render() {
return (
<section>
n : {this.state.n}
<button onClick={this.addN} > + 1</button>
</section>
)
}
}
此时的addN是是不在原型链上的,而是在实例上的,而且由于箭头函数没有this,所以this会直接指向实例,会正确触发函数。
vue 与 react 的区别
- 相同
vue和react都是对视图的封装。
-
vue通过构造选项表示组件
-
react通过类/函数表示组件
都提供了createElement的简写
-
react——jsx
-
vue——template模板语法
- 不同
react将html放在js中写
vue将js放在html中写