React组件基础
React事件机制
在react中,如果你写<div onClick={()=>{}}></div>
,react不是将click事件绑定到了真实DOM上,而是使用了document监听了所有的事件,采用事件代理的方式。react是将事件中的内容处理成函数,当事件冒泡到document后直接调用函数执行。这样做的好处就是:
-
不用给每个DOM都绑定事件,减少内存的消耗。
-
在组件销毁时统一移除事件。
react中,冒泡到document上的事件不是浏览器的原生事件,而是react自己实现的合成事件。
//原始DOM
<div onclick="fn()"></div>
//react合成事件
<div onClick={fn}></div>
合成事件的优点:
-
磨平了浏览器之间的兼容性问题。
-
因为这个是react跨浏览器包装的,所以赋予了跨浏览器开发能力。
-
减少了内存的消耗。
React高阶组件
react高阶组件就是一个函数,它接收一个组件作为参数,并且返回一个组件。
优点:
-
代码复用
-
渲染劫持,鉴权
-
state更改
-
props更改
示例:
-
鉴权
import React from 'react'
export default function AuthComponent(Component) {
const Test = (props) => {
const { login } = props;
if(login){
return <Component {...props}/>
}else{
return <div>没有登录</div>
}
}
return Test;
}
import React from 'react'
import AuthComponent from '../AuthComponent'
const Login = function Login() {
return (
<div>Login</div>
)
}
export default AuthComponent(Login);
import Login from "./components/login";
function App() {
return (
<div>
<Login login={true} />
</div>
);
}
export default App;
-
页面复用
//App.js
import {NewList, AttentionList} from "./components/list";
function App() {
return (
<div>
<NewList />
<AttentionList />
</div>
);
}
export default App;
//list.js
import React from 'react'
import withFetching from '../WrappedComponent'
const List = (props) => {
return (
<div>{props.data}</div>
)
}
export const NewList = withFetching(()=>'NewList')(List);
export const AttentionList = withFetching(()=>'AttentionList')(List);
//WrappedComponent.js
import React, { useEffect, useState } from 'react'
const withFetching = fetching => WrappedComponent => {
const Fetch = (props) => {
const [data, setData] = useState('');
useEffect(()=>{
//这里可以换成请求axios接口
setData(fetching());
},[]);
return <WrappedComponent data={data} {...props} />
}
return Fetch;
}
export default withFetching;
哪些方法会触发React重新渲染,重新渲染render会做什么?
哪些方法会触发React重新渲染:
-
父组件的重新渲染。
-
this.setState改变组件的值的时候,注意点是如果this.setState传入的是null则不会重新渲染render。
-
使用useState hooks更新值的时候。重新渲染render会做什么:
-
会对新旧虚拟DOM进行比较,也就是diff算法。
-
对新旧虚拟DOM树进行深度优先的遍历。
React状态组件和无状态组件
React受控组件和非受控组件
受控组件:比如用户在使用表单来收集用户的输入时,input
、textearea
都要绑定一个onChange事件,当用户输入的时候就调用setState来改变值,这就让渲染的值与input
上的value属性相对,让整个状态可控。
受控组件的缺点,如果输入框多的话,就需要给每一个输入框都绑定一个onChange事件,会让代码显得十分臃肿。所以就出现了非受控组件。
非受控组件:非受控组件就是使用ref从DOM上获取值,不用每个输入框都绑定一个onChange事件。
React类组件和函数组件的相同点和不同点。
相同点:它们都是React中可复用的最小代码片段,所以他们的使用方式和显示效果都一样,你甚至可以把函数组件改写成类组件,把类组件改写成函数组件。
不同点:
-
心智模型不同,类组件面向对象编程,主打的是生命周期和继承。而函数组件内核是函数式编程,主打immutable、没有副作用、引用透明。
-
在以前的使用场景中,如果需要使用生命周期的话和继承的话就使用类组件,但是现在React Hook的推出,让生命周期的概念渐渐消失。
-
性能优化上,类组件使用的shouldComponentUpdate来阻断渲染的更新,而函数组件使用React.memo来缓存渲染结果。
-
上手程度上,我个人认为类组件较容易上手,但是现在React Hook推出,让函数式编程成了主流方案。
-
函数组件比较轻量级,类组件的生命周期如果过多,就会显得很复杂,则不易优化。