函数组件
函数组件没有声明周期和state
概念和定义
函数组件是函数式编程,通过接收一个props
对象返回一个react元素,特点是不可变的、引用透明且没有副作用等
import React from 'react'; //function App(props){ // return ( // <div> xxx </div> // ) //} const App = (props) =>{ return <h1> xxx </h1> } export default App
生命周期
函数组件不存在生命周期,生命周期钩子函数都来自于继承的React.Component
,而函数组件不需要继承
但函数组件可以通过使用useEffect
代替生命周期的作用:
const function = () => {//对应类组件中的componentDidMount生命周期。 useEffect(() => { console.log("hi"); }, []); return <h1>Hello, World</h1>; };
如果在useEffect
回调函数中return一个函数,则return函数会在组件卸载的时候执行,正如componentWillUnmount
const Functiona = () => { React.useEffect(() => { return () => { console.log("Bye"); }; }, []); return <h1>Bye, World</h1>; };
状态state
在react16.8版本中添加了hooks
,使得我们可以在函数组件中使用useState钩子去管理state,使用useEffect
钩子去使用生命周期函数。
函数组件没有this,要管理state,只能使用一系列的内置hooks实现对应的功能,如使用useState
创建状态变量
const Functiona = () => { const [count, setCount] = React.useState(0); return ( <div> <p>count: {count}</p > <button onClick={() => setCount(count + 1)}>Click</button> </div> ); };
在使用hooks情况下,一般如果函数组件调用state,则需要创建一个类组件或者state
提升到你的父组件中,然后通过props
对象传递到子组件。
调用方式
函数组件调用执行函数:
function SayHi(){ return <h1>Hello,World</h1> } const result = SayHi(props)
如何获取渲染的值
函数组件捕获了渲染所用的值
首先先看以下例子,它渲染了一个利用setTimeout
来模拟网络请求,然后显示一个确认警告的按钮。例如,如果props.user
是Dan
,它会在三秒后显示Followed Dan
。非常简单
// 函数式组件对应如下: function ProfilePage(props) { const showMessage = () => { alert('Followed ' + props.user); } const handleClick = () => { setTimeout(showMessage, 3000); } return ( <button onClick={handleClick}>Follow</button> ) }
类组件
继承React.Component
并创建render函数返回react元素
概念和定义
类组件是面向对象编程,主要是继承和生命周期等核心概念,但面向对象编程将属性和方法封装起来,屏蔽了很多细节,不利于测试,而且react的设计思路更推崇组合,而不是继承,因此在类组件中大量使用继承会造成组件过重,功能难以拆分
import React from 'react'; class App extends React.Component{ constructor(props){ super(props) } render(){ return ( <div> xxx </div> ) } } export default App
生命周期
生命周期的含义是指事物从创建到最后消亡经历的整个过程,在react,组件的生命周期是指组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程
钩子函数(只有类组件才有生命周期钩子函数):在生命周期的不同阶段,会自动被调用执行的函数
类组件的生命周期主要可以分为三个状态:挂载、更新、卸载,共有五个钩子函数。
生命周期图查看:React lifecycle methods diagram
常用的生命周期:
不常用的生命周期:
挂载阶段(Mount)
在组件创建时或者页面加载时执行,挂载之后调用componentDidMount()
方法
相关钩子函数:
钩子函数 | 执行 | 作用 | |
---|---|---|---|
constucttor | 创建组件时执行 | 初始化state | |
render | 组件渲染都会执行 | 渲染页面UI | |
componentDidMount | 组件挂载完成之后 | 发送网络请求、完成DOM操作 |
更新阶段(Update)
当组件的state或props改变时就会更新组件,更新后调用componentUpdate()
方法
如何触发组件更新:
-
调用setState
-
调用forceUpdate,强制更新
-
组件接收到新的props
相关钩子函数:
钩子函数 | 执行 | 作用 |
---|---|---|
render | 组件渲染都会执行 | 渲染页面UI |
componentUpdate | 组件更新 | 获取到更新后的DOM |
卸载阶段(Unmount)
当组件从DOM上移出时调用componentWillUnmount()
方法
相关的钩子函数:
钩子函数 | 执行 | 作用 |
---|---|---|
componentWillUnmount | 组件卸载时 | 移出事件、清理定时器等 |
state
创建定义state
class App extends React.Component { constructor(props) { super(props); this.state = { data:{}, }; } render() { return ( <div> <h1>Hello, world!</h1> <h1>this.state.data</h1> </div> ); } }
修改state
class App extends React.Component { constructor(props) {//构造函数是唯一可以给 this.state 赋值的地方 super(props); this.state = { data:{}, }; } change = () => { const data = this.sate data = "helloWorld" this.setState({ data:data }) } render() { return ( <div> <h1>Hello, world!</h1> <h1>this.state.data</h1> </div> ); } }
调用方式
calss SayHi extends React.Component{ render(){ return <h1>Hello World </h1> } } const instance = new SayHi(props); const result = instance.render()
如何获取渲染的值
// 类组件对应如下: class ProfilePage extends React.Component { showMessage() { alert('Followed ' + this.props.user); } handleClick() { setTimeout(this.showMessage.bind(this), 3000); } render() { return <button onClick={this.handleClick.bind(this)}>Follow</button> } }