React核心基础(上)
React的核心基础笔记
程序猿最烦两件事,第一件事是别人要他给自己的代码写文档,第二件呢?是别人的程序没有留下文档。小编今天给大家总结了一份文档,都是我在学习react的时候的一些心得体会,可能不够官方,都是用我自己的大白话进行说明的,有不足的地方希望大佬指正。

文章目录
- React的核心基础笔记
- 一、React介绍:
- 起源:
- 阐述:
- 特点:
- 学习网站推荐:
- 二、开发环境搭建
- cdn引入js(不使用脚手架)
- 使用脚手架工具创建项目
- 三、React核心基础
- helloReact(第一个react程序)
- jsx语法:
- 概念:
- 语法规则:
- 操作元素
- Fragments:
- 列表渲染
- 条件渲染:
- State组件内部数据
- 事件
- 绑定事件的写法二(需要修正this)
- 在构造器中修正this
- 绑定事件的写法三(箭头函数)
- 绑定事件的写法四
- 事件对象和默认行为
- 四、组件之间的通信
- 父传子
- 父组件代码
- 子组件代码
- 子传父
- 兄弟组件传值
- 提供者和消费者
- ref操作节点
- 五、react生命周期
- 三种执行阶段
- 初始化阶段
- 运行阶段
- 销毁阶段
- 完整的总代码演示
- 在生命周期中创建和销毁一个定时器
- 六、函数式组件-hook
- hook简介:
- hook特点:
- 使用state Hook:
- Effect Hook(副作用)
- 执行的时机
- 普通的副作用
- hook之间的提供者和消费者传参
一、React介绍:
-
起源:
- React 起源于 Facebook 于2013年5月开源.是一个用于构建用户界面的 JavaScript 库, 与vue,angular并称前端三大框架,现在最新版本是18
-
阐述:
- 它只提供 UI (view)层面的解决方案在实际的项目当中,它并不能解决我们所有的问题,需要结合其它的库,例如 Redux、React-router 等来协助提供完整的解决方法。
-
特点:
- 数据驱动
- 组件化
- 虚拟DOM
-
学习网站推荐:
- 英文官网: https://reactjs.org/
- 中文官网: https://zh-hans.reactjs.org/
- 官网文档:https://react.docschina.org
二、开发环境搭建
-
cdn引入js(不使用脚手架)
-
安装npm包
npm i react@17.0.0 react-dom@17.0.0 babel-standalone@6.26.0 //简单解释一下 react@17.0.0 // react核心 react-dom@17.0.0 //负责渲染 babel-standalone@6.26.0 // es6转es5 -
在html文档中引入
<script src="./node_modules/react/umd/react.development.js">script> <script src="./node_modules/react-dom/umd/react-dom.production.min.js">script> <script src="./node_modules/babel-standalone/babel.js">script> -
将 script 标签中的jsx内容转换为浏览器可以识别的 JavaScript
<script type="text/babel">script>
-
-
使用脚手架工具创建项目
-
使用npm包管理工具
npx create-react-app my-app //创建一个react项目 cd my-app//去到项目文件夹 npm start//启动项目
-
三、React核心基础
-
helloReact(第一个react程序)
DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Documenttitle><script src="./node_modules/react/umd/react.development.js">script><script src="./node_modules/react-dom/umd/react-dom.production.min.js">script><script src="./node_modules/babel-standalone/babel.js">script> head> <body><div id="root">div><script type="text/babel">// ReactDOM.render(渲染的h2元素节点,渲染到root根节点去)ReactDOM.render(<h2>helloreact</h2>,document.getElementById('root'))script> body> html> -
jsx语法:
-
概念:
- JSX 全称 JavaScript XML ,是一种扩展的 JavaScript 语言,它允许 HTML 语言直接写在 JavaScript 语言中,不加任何引号,这就是 JSX 语法。它允许 HTML 与 JavaScript 的混写。
-
语法规则:
- 必须只能有一个根节点
- *小括号()的内容当成html元素解析
- *插入js代码用大括号{}
- 单标签不能省略结束标签。/>
- JSX 允许直接在模板中插入一个 JavaScript 表达式
-
示例
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./node_modules/react/umd/react.development.js"></script><script src="./node_modules/react-dom/umd/react-dom.production.min.js"></script><script src="./node_modules/babel-standalone/babel.js"></script> </head> <body><div id="root"></div><script type="text/babel">/* 多行的react元素,必须有根元素*/// 定义变量let message = '第一个react程序'let user = {name:'jack',age:18}let list = ['我是数组1','我是数组2']let person = {name:'我是一个对象'}// 定义元素// 1、小括号()的内容当成html元素解析// 2、插入js代码用大括号{}// 3、jsx就是javaScript XML,是一种扩展的js语言// 它允许 HTML 语言直接写在 JavaScript 语言中,不加任何引号,这就是 JSX 语法。// 它允许 HTML 与 JavaScript 的混写。const element =(<div><h2>{message}</h2> <p>姓名:{user.name}</p><p>年龄:{user.age}</p><p>数组:{list[0]}</p><p>对象:{person.name}</p></div>)ReactDOM.render(element,document.getElementById('root'))</script> </body> </html>网页显示效果如下第一个react程序 姓名:jack年龄:18数组:我是数组1对象:我是一个对象
-
-
操作元素

-
操作内容
-
操作属性
-
操作样式
DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Documenttitle><script src="./node_modules/react/umd/react.development.js">script><script src="./node_modules/react-dom/umd/react-dom.production.min.js">script><script src="./node_modules/babel-standalone/babel.js">script> head> <body><div id="root">div><script type="text/babel">let title = '操作内容'let url = 'https://www.baidu.com/'let sty = {color:'red',fontSize:'18px'}// 绑定点击事件函数function bindClick(){alert('我是绑定点击事件')}// 定义元素内容const element = (<div><button onClick={bindClick}>我是一个绑定事件按钮</button>{/* 操作内容 */}<h2>{title}</h2>{/* 操作属性 */}<a href={url}>跳转百度</a>{/* 操作样式 */}<p style={sty}>操作样式变红</p>{/* 直接写一个对象操作样式 */}<p style={{color:'blue'}}>直接写一个样式变蓝</p></div>)ReactDOM.render(element,document.getElementById('root'))script> body> html>
-
-
Fragments:
-
概念:Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。
-
简写:
<>> -
示例:
<React.Fragment><h2>列表h2><ul><li>元素一li><li>元素二li>ul> React.Fragment>
-
-
列表渲染
-
概念:与vue里面的v-for比起来复杂点,这里使用的是map方法
-

-
示例:
DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>helloworldtitle><script src="./js/react.development.js">script><script src="./js/react-dom.development.js">script><script src="./js/babel.js">script><style>ul,li {list-style: none;}.y-table {width: 80%;margin: 0 auto;}.y-table tr,td {border-bottom: 1px dotted gray;}style> head><body><div id="root">div><script type="text/babel">let list = [{ id: 1001, name: 'javascript高级编程', price: 88.78 },{ id: 1002, name: 'vue高级编程', price: 188.58 },{ id: 1003, name: 'react高级编程', price: 288.59 },]const element = (<div><h2>列表渲染</h2><ul>{list.map(item => (<li>{item.id} - {item.name} - {item.price}</li>))}</ul><h2>列表渲染table表格</h2><table className="y-table">{list.map(item => (<tr key={item.id}><td>{item.id}</td><td>{item.name}</td><td>{item.price}</td></tr>))}</table></div>)ReactDOM.render(element, document.getElementById('root'))script> body>html>
-
-
条件渲染:
-
概念:通过if语句、三元运算符、逻辑与或非运算符进行运算
-

-
示例:
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./node_modules/react/umd/react.development.js"></script><script src="./node_modules/react-dom/umd/react-dom.production.min.js"></script><script src="./node_modules/babel-standalone/babel.js"></script></head><body><div id="root"></div><script type="text/babel">let age = 19function getUser(flag){if(flag == 0){return <h2>我是在线的状态</h2>}else if(flag == 1){return <h2>我是离线状态</h2>}else if(flag == 2){return <h2>我是隐身的状态</h2>}}const element = (<div>{/* 通过if语句进行条件判断 */}{getUser(0)}{getUser(1)}{getUser(2)}{/* 通过三元运算符 表达式?真:假 */}{age >18?<h2>成年人</h2>:<h2>未成年人</h2>}{/* 通过与或非表达式 */}{age > 18 && <h2>成年人</h2>}</div>) ReactDOM.render(element,document.getElementById('root'))</script> </body></html>
-
-
State组件内部数据
-
概念:state,叫做状态,是用来盛放数据的。
-
一般写法示例:
import React, { Component } from "react";export default class App extends Component {// 定义state的第一种方式// 这种方式就是构造器的方式constructor() {super(); // 因为继承了父类 所以需要使用super 函数this.state = {num: 0,uname: "zrs",};}render() {return (<div>{/* 使用状态 */}{this.state.num}-{this.state.uname}</div>);}
}
-
简写示例
import React, { Component } from "react";export default class App extends Component {// 定义状态的第二种方式state = {num: 0,uname: "zrs",};render() {return (<div>{/* 使用方式没有任何变化 */}{this.state.num}-{this.state.uname}</div>);} }
-
注意事项:
- 在点击事件函数中的this,指向的是undefined
- 在构造器里面改变点击事件函数的this指向,将它从新指向为事件源
- 使用箭头函数this指向是上下文的特殊性,来改变this指向
-
绑定事件写法一
-
直接在大括号里面写一个箭头函数、在函数中直接书写逻辑代码;缺点:逻辑代码写太多维护起来就会很复杂
import React, { Component } from "react";export default class App extends Component {state = {uname: "zrs",};render() {return (<div><buttononClick={() => {let uname = "zzr";// 这里的 this 指向的是 实例对象console.log("this:", this);// 改变 state 的值 请使用 setState() 这个函数在修改值之后,才能触发render函数重新执行this.setState({uname,});}}>change</button><div>{this.state.uname}</div></div>);}
}
import React, { Component } from "react";export default class App extends Component {state = {uname: "zrs",};// 将事件处理函数写在 外面 但是这种写法会有一个问题 就是需要修正this ,如果不修正this,this指向的是undefined// 这个不是react留的坑,是js的坑,详情自行搜索changeUname() {let uname = "zzr";console.log("this:", this);this.setState({uname,});}render() {return (<div>{/* 使用bind 函数修正 this */}<button onClick={this.changeUname.bind(this)}>change</button><div>{this.state.uname}</div></div>);}
}
-
在构造器中修正this
import React, { Component } from "react";export default class App extends Component {constructor(){super()// 在构造器中修正thisthis.changeUname=this.changeUname.bind(this)}state = {uname: "zrs",};changeUname() {let uname = "zzr";console.log("this:", this);this.setState({uname,});}render() {return (<div><button onClick={ this.changeUname }>change</button><div>{this.state.uname}</div></div>);} } -
绑定事件的写法三(箭头函数)
import React, { Component } from "react";export default class App extends Component {state = {uname: "zrs",};// 在这里写成箭头函数即可,因为箭头函数的this指向的是应用上下文changeUname = () => {let uname = "zzr";console.log("this:", this);this.setState({uname,});};render() {return (<div><button onClick={this.changeUname}>change</button><div>{this.state.uname}</div></div>);} } -
绑定事件的写法四
import React, { Component } from "react";export default class App extends Component {state = {uname: "zrs",};changeUname = () => {let uname = "zzr";console.log("this:", this);this.setState({uname,});};render() {return (<div>{/* 第四种写法:给事件一个处理函数,在处理函数中调用处理逻辑的函数 所以这里添加了小括号 */}<button onClick={() => {this.changeUname()}} >change</button><div>{this.state.uname}</div></div>);} }
-
事件对象和默认行为
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>事件对象与事件默认行为</title><script src="./js/react.development.js"></script><script src="./js/react-dom.development.js"></script><script src="./js/babel.js"></script></head><body><div id="root"></div><script type="text/babel">class Counter extends React.Component{state = {url:'http://www.baidu.com'}render(){return (<div><button onClick={ (e)=>{this.bindClick(e,this.state.url)} }>确定</button><a href={this.state.url} onClick={this.bindBaidu}>百度</a></div>)}bindClick = (e,url)=>{console.log('触发点击事件 事件对象event : ',url, e);}bindBaidu = (e)=>{e.preventDefault()console.log('触发事件');}}ReactDOM.render(<Counter/>, document.getElementById('root'))</script></body> </html>
四、组件之间的通信
import React, { Component } from "react";
import Son from "./son";//引入子组件export default class 我是父组件 extends Component {state = {// 这是父元素里面的参数msg: "我是父传子的参数123",};render() {return (<div><h2>我是父组件</h2>{/* 自定义一个属性,把父组件的值传入进去 */}<Son info={this.state.msg}/></div>);}
}
import React, { Component } from 'react'export default class 我是子组件 extends Component {render() {return (<div><h4>我是子组件</h4><h4>{this.props.info}</h4></div>)}
}
-
父传子视图
-

-
概念:子传父就是在使用子组件的时候,将函数传给子组件,子组件触发该函数,修改父组件中的值
-
子组件
import React, { Component } from 'react'
export default class son1 extends Component {state={sonMsg:'我是子组件信息' //子组件的信息}render() {return (<div className='son'><h3>我是子组件</h3><button//定义一个点击事件,调用props里面的callback// 然后将子组件的参数,作为实参传入给callback这个函数 onClick={()=>{this.props.callback(this.state.sonMsg)}}>子传父按钮</button></div>)}
}
- 父组件
import React, { Component } from 'react'
import Son1 from './son1'//引入子组件
import './ftos.css' //引入样式
export default class father1 extends Component {state={fatherMsg:'我是父组件原本信息'}render() {return (<div className='father'><h2>我是父组件</h2><h3>{this.state.fatherMsg}</h3><Son1 callback={(msg)=>{this.getMssage(msg)}}/></div>)}// msg作为形参,然后setState给faterMsggetMssage=(msg)=>{this.setState({fatherMsg:msg})}
}
- 子传父图示
-
-
概念:就是兄弟组件通过同一个父组件,一个子组件负责传值,另一个子组件负责接受参数
-
父组件代码
import React, { Component } from 'react'
import Son1 from './son1'
import Son2 from './son2'
import './btob.css'
export default class father extends Component {state={fatherMsg:''}render() {return (<div className='father'><h1>我是两个子组件的父组件</h1><p>{this.state.fatherMsg}</p><Son1 callback={(msg)=>{this.getMessage(msg)}}/><Son2 info={this.state.fatherMsg}/></div>)}getMessage = (msg)=>{this.setState({fatherMsg:msg})}
}
- 子组件传值
import React, { Component } from "react";export default class extends Component {state = {sendMsg: "我是子组件发送信息",};render() {return (<div className="son1"><h2>我是子组件发送者11</h2><buttononClick={() => {this.props.callback(this.state.sendMsg);}}>点击发送son1组件信息</button></div>);}
}
- 子组件接受值
import React, { Component } from 'react'export default class extends Component {render() {return (<div className='son2'><h2>我是子组件接收者</h2> <p>{this.props.info}</p></div>)}
}
-
兄弟组件传参图示
-

-
提供者与消费者可用来实现跨级通信,提供者
provider提供数据,消费者consumer使用数据。需要注意的是provider有一个固定的属性value,consumer需要使用函数然后返回jsx的形式,这样设计便于传参。 -
提供者
import React, { Component } from "react";import Consumer1 from "./Consumer";// 创建一个 context 对象
export const { Provider, Consumer } = React.createContext();export default class App extends Component {state = {info: "父组件的信息",};render() {return (<Provider// value 是固定的写法value={{uname: "这里是父组件传递给子组件的",info: this.state.info,changInfo: (info1) => {this.setState({ info: info1 });},}}><div>父组件</div><Consumer1 /></Provider>);}
}
- 消费者
import React, { Component } from "react";// 这里引入的消费者 对象 必须是和 提供者配对的
import { Consumer } from "./Provider";export default class Son extends Component {render() {return (<Consumer>{/* // 这里的value 就是提供者的那个value里面的值 */}{(value) => (<div>子组件 {value.uname}---{value.info}<buttononClick={() => {value.changInfo("12312314323454");}}>change</button></div>)}</Consumer>);}
}
-
概念:通过在元素中绑定ref,来操作节点
-
示例
-
父组件
import React, { Component } from 'react'import Son from './Son' export default class father extends Component {myrefH2 = React.createRef() //myrefSon = React.createRef()render() {return (<div>{/* ref可以绑定标签元素 */}<h2 ref={this.myrefH2}>我是一个h2标签</h2><button onClick={()=>{console.log(this.myrefH2);console.log(this.myrefH2.current);}}>查看myrefH2按钮</button><Son ref={this.myrefSon}/><button onClick={()=>{console.log(this.myrefSon);console.log(this.myrefSon.current);console.log(this.myrefSon.current.state);}}>查看myrefSon按钮</button></div>)} } -
子组件
import React, { Component } from 'react'export default class Son extends Component {state={msg:'我是子组件的state数据'}render() {return (<div><h3>我是子组件</h3></div>)} } -
图示
-

五、react生命周期
- 概念:
- React生命周期指 React组件实例从创建运行到销毁经历的一系列过程。
- 注意react的函数式组件没有生命周期函数这一说,函数式组件要实现生命周期的功能,需要在副作用函数中实现。下面介绍的是类组件的生命周期函数。

- 先执行 `constructor` 函数 =》然后是 `render` 函数 =》然后是 `componentDidMount` 函数。/*** 这个函数会在render函数执行之后立即执行,* 1. 这时这个函数中可以执行一些关于dom的操作* 2. 也可以做一些请求后端数据的工作* 3. 也可以做一些定时器之类的活*/componentDidMount() {console.log("初始化阶段的最后一个执行函数");}
- 先执行render函数=》然后就是`componentDidUpdate `函数/*** 该函数有三个参数* 第一个参数是之前的属性* 第二个参数是之前的状态* * 在这个函数中做一些操作,都需要在判断条件中执行,不然很容易造成死循环*/componentDidUpdate(prevProps, prevState) {console.log(prevProps, prevState);console.log("更新阶段");}
// 这个函数在组件销毁的时候执行componentWillUnmount() {console.log("组件销毁了");}
import React, { Component } from "react";import Demo from "./Demo";
export default class App extends Component {state = {flag: true,};render() {return (<div><h2>App</h2>{this.state.flag && <Demo />}<buttononClick={() => {let flag = this.state.flag;flag = !flag;this.setState({ flag });}}>显示/隐藏子组件</button></div>);}
}
2. 子组件
import React, { Component } from "react";export default class Demo extends Component {constructor() {super();this.state = {num: 0,};}render() {return (<div>Demo<h2>{this.state.num}</h2><buttononClick={() => {let num = this.state.num;num++;this.setState({ num });}}>chang</button></div>);}/*** 这个函数会在render函数执行之后立即执行,这个函数只会执行一次* 1. 这时这个函数中可以执行一些关于dom的操作* 2. 也可以做一些请求后端数据的工作* 3. 也可以做一些定时器之类的活*/componentDidMount() {console.log("初始化阶段的最后一个执行函数");}/*** 该函数有三个参数* 第一个参数是之前的属性* 第二个参数是之前的状态* * 在这个函数中做一些操作,都需要在判断条件中执行,不然很容易造成死循环*/componentDidUpdate() {console.log("更新阶段");}// 这个函数在组件销毁的时候执行,这个函数只会执行一次componentWillUnmount() {console.log("组件销毁了");}}
import React, { Component } from 'react'
import Date from './Date'
export default class Myapp extends Component {state={flag:false}render() {return (<div><h2>我是app主页</h2>{/* 设置一个点击事件,对state状态值进行管理 */}<button onClick={this.undate}>隐藏或显示组件</button>{/* 如果为真就显示组件、如果为假就不显示组件 */}{this.state.flag?<Date/>:null}</div>)}undate= ()=>{let flag = this.state.flagflag = !flagthis.setState({flag})if(flag){alert('已经显示组件')}}
}
2. 子组件
import React, { Component } from 'react'export default class Clock extends Component {state = {date: new Date(),}render() {return (<div><h2>电子时钟</h2>{this.state.date.toLocaleTimeString()}</div>)}componentDidMount() {this.timer()// 在挂载的时候调用,定时器console.log('完成挂载');}componentDidUpdate() {console.log('完成更新')}// 定时器timer() {this.intervalTimer = setInterval(() => {this.setState({ date: new Date() })}, 1000)}componentWillUnmount() {console.log('Clock componentWillUnmount')clearInterval(this.intervalTimer) //清除定时器}
}

六、函数式组件-hook
-
hook简介:
- Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。
- Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React, Hook 是 React 16.8 的新增特性。
- 常用Hook: useState() useEffect() useRef() useContext()
-
hook特点:
- 在组件之间复用状态逻辑, 无需修改组件结构
- 将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据),而并非强制按照生命周期划分
- 不编写 class 的情况下使用 state 以及其他的 React 特性
-
使用state Hook:
- 在函数组件里没有this指向的问题,直接调用
- useState会返回一对值,当前状态和更新状态。还有初始值
import React,{useState} from 'react'export default function Testhook() {// [参数,设置参数] = useState(参数的初始值)const [num,setNum] = useState(0)// [参数,设置参数] = useState(参数的初始值)const [msg,setMsg] = useState('初始值')return (<div>{/* 在函数组件里面没有this指向问题,直接调用定义好的参数 */}<h2>直接使用num数值</h2><h3>{num}</h3>{/* 点击更改设置好的参数 */}<button onClick={()=>{setNum(num+1)}}>点击num加一</button><h2>直接使用msg字符串</h2><h3>{msg}</h3><button onClick={()=>{setMsg('已经更改msg信息')}}>点击更改msg信息</button></div>
)
}
-
Effect Hook(副作用)
-
函数组件主要作用是通过数据渲染UI界面,除了这个之外的操作就是副作用。
-
ajax请求
-
手动修改dom
-
localstorage操作
-
-
执行的时机
- 默认状态=>首次执行、每次组件更新
- 添加空[ ]=>首次执行
- 添加依赖项[count]=>首次执行、依赖项发生变化
-
普通的副作用
js
import React,{useState,useEffect}from 'react'export default function Fzy() {const [num,setNum] = useState(0)const [msg,setMsg] = useState('初始值')useEffect(()=>{console.log('副作用只有一个参数的时候,在初始化和组件刷新的时候调用');})useEffect(()=>{console.log('副作用第二参数是一个空数组的时候,只有初始化的时候调用');},[])useEffect(()=>{console.log('副作用第二参数有值的时候,初始化和只要数组里面的值变化,就触发函数');},[num])return (<div><h2>查看num的值</h2><p>{num}</p><button onClick={()=>{setNum(num+1)}}>点击加一</button></div>)
}

- 利用副作用清除定时器
- 父组件
import React, { Component } from 'react'
// import Date from './Date'
import HookDate from './HookDate'
export default class Myapp extends Component {state={flag:false}render() {return (<div><h2>我是app主页</h2>{/* 设置一个点击事件,对state状态值进行管理 */}<button onClick={this.undate}>隐藏或显示组件</button>{/* 如果为真就显示组件、如果为假就不显示组件 */}{this.state.flag?<HookDate/>:null}</div>)}undate= ()=>{let flag = this.state.flagflag = !flagthis.setState({flag})if(flag){alert('已经显示组件')}}
}
2. 子组件
import React,{useState,useEffect} from 'react'//导入方法export default function HookDate() {const [date,setDate] =useState('')useEffect(()=>{// 定义一个计时器let interValTimer = setInterval(()=>{let time = new Date().toLocaleTimeString()setDate(time)//将获取到的值设置给date},1000)// 清理副作用方法return ()=>{console.log('清理副作用');clearInterval(interValTimer)}},[])return (<div><h2>我是子组件时钟</h2>{date}</div>)
}

import React from "react";
// 引入子组件
import Demo from "./Son";// 创建一个 context 对象 导出一下,
// 因为子组件需要使用这个对象中的一个消费者对象
export const GlobalContext = React.createContext();export default function App() {return (<GlobalContext.Providervalue={{val: "我是来自父组件的传值",num: 1234,}}><h2>我是父组件</h2><Demo /></GlobalContext.Provider>);
}
1. 消费者
import React, { useContext } from "react";
// 引入导出的那个 context 对象
import { GlobalContext } from "./Father";export default function ComC() {// 使用 useContext 的使用 将导入的 context 对象作为参数传入
// 这个函数会返回 提供者的 value属性的值const text = useContext(GlobalContext);return (<div><h3>我是子组件</h3><p>接受父组件val:{text.val}</p><p>接受父组件num:{text.num}</p></div>);
}
- 自定义hook
- 自定义hook文件(必须是use开头)
import { useState } from "react";
// 这个函数就是自定义的 hook
export function useScrollTop() {// 还是定义一个useStateconst [height, setheight] = useState(0);// 只要检测到左边滑轮就设置一次setheightwindow.addEventListener("scroll", () => {let h = document.documentElement.scrollTop;setheight(h);});// 把获取到的值返回return [height];
}
2. 引入我的自定义hook
import React, { useContext,useState } from "react";
// 引入自定义hook
import {useScrollTop} from './useScrollTop'
import './my.css'//引入一个高度样式height10000export default function ComC() {// 使用引入的useScrollTopconst [scrollTop,setscrollTop] = useScrollTop(0)return (<div className="h"><p>{scrollTop}</p></div>);
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
