欢迎大家纠错......
1.react基础
1.安装
react npm i react, npm i react-dom
2.react核心方法 const ele = React.createdElement('h', {}, '我是标题一')
//参数说明
第一个参数:需要创建的标签名
第二个参数:需要创建标签所携带的属性
第三个参数及以后的参数:创建标签的子节点包括文本节点
ReactDom.render(ele, document.body)
//参数说明 第一个参数:需要挂在的react元素
第二个参数:挂载点
2.利用react脚手架创建项目
1.初始化项目
npx create-react-app my-app (node版本需要在14.0.0及以上) 或者
npm init react-app my-app 或者 yarn create react-app my-app
2.启动项目 cd 到项目内层 npm start 或者 yarn start
npx与npm区别
npx:可以运行使用nodejs构建并通过npm仓库发布的代码
特点:无需安装脚手架包,就可以使用脚手命令来创建项目
3.jsx语法
前言:
jsx并不是标准的ECMAScript的语法,它是ECMAScript语法的扩展 jsx需要babel编译之后,
才能在浏览器中使用 react中编译jsx语法的包是:@babel/preset-react
注意:jsx语法中元素的属性名使用驼峰命名法
1.变量 jsx语法中用{}包裹变量
const name = 'Jack' const ele = ( <h1>我叫{name}!</h1> )
2.列表渲染
jsx中使用map去循环列表进行渲染 需要设置唯一索引key,避免使用index为索引
4.react组件
1.函数组件
定义:使用js的函数(或者箭头函数)创建的组件
约定:函数名必须大写,函数组件必须有返回值,如果返回值是null则什么也不渲染
例 function Hello(){ return (<div>我是一个函数组件</div>) }
2.类组件
定义:利用class创建的组件
约定:类名必须大写,类组件必须有返回值,类组件应该继承React.component,
从而可是使用父组件中的方法;类组件必须实现render方法,render方法必须要有返回值
例 class Hello extends
React.Componnet{ render(){ return (<div>这是一个类组件</div>) } }
区别:类组件中可以使用this,函数组件无this
5.组件中的state和setState
1.state
state是用来存储数据的,只能在组件内部使用
获取:用this.state.变量名来获取state
2.setState()方法
setState方法可以传入一个对象,对象内容是需要修改的字段和字段对应的值
setState方法内部做了什么:
(1)改变变量值
(2)更新ui
注意:直接用this.state = 2这样的语法是错误的 setState改变变量的方法是异步的
5.非受控组件
建议:这种方式是直接操纵dom,建议少用
import logo from './logo.svg'; import './App.css';
import React from 'react';
class App extends React.Component{
constructor(){
super()
this.state ={count:0,txt:'',city:'sh',check:false}
this.txtRef = React.createRef()
}
getText = () => {
console.log(this.txtRef.current.value, 'val')
}
render(){
return(
<div>
<p>非受控组件</p>
<br/>
<input type='text' ref={this.txtRef}></input>
<button onClick={this.getText}>获取文本框的值</button>
</div>
)
}
}
export default App
6.组件之间的通信
1.父传子
class Parent extends React.component{
render(){
return (
<div>
<Child1 name="child1"/>
<Child2 name="child2"/>
</div>
)
}
}
class Child1 extends React.component{
constructor(props){
super(props)
}
render(){
return (
<div>{this.props.name}</div>
)
}
}
function Child2(props){
return (
<div>{props.name}</div>
)
}
2.子传父
class Parent extends React.component{
getChildMsg = (data) => {
console.log(data)
}
render(){
return (
<div>
<Child1 name="child1" getMsg="this.getChildMsg"/>
</div>
)
}
}
class Child extends React.component{
constructor(props){
super(props)
this.state = {
name:'父组件传递子组件的数据'
}
}
handleClick = () => {
this.props.getMsg(this.state.name)
}
render(){
return (
<div>
<button onClick="handleClick">传递数据到父组件</button>
</div>
)
}
}
3.兄弟组件传参
通过共同的父组件管理
4.父传深层次的后代
context方式
7.props校验
1.props的校验规则
引入prop-types模块
import PropTypes from 'prop-types'
class App extends React.component{
}
App.propTypes ={
name:PropTypes.string
}
2.常用的效验规则
string,number,array,object,func,bool,symbol
指定结构类型用shape
必填:isRequired
8.props默认值
1.设置默认值
class App extends React.component{
}
App.defaultProps = {
name:'我是name属性的默认值'
}
9.组件的生命周期
注意:只有类组件才有生命周期
1.创建时
constructor
组件创建时,最先执行
作用:初始化state,为事件处理程序绑定this
render
每次ui发生变化都会执行
作用:渲染ui,注意不能在此方法中调用setState
componentDidMount
组件挂载完后
作用:可以获取dom,进行网络请求
2.更新时
componentDidUpdate
组件更新时执行
//导致组件更新的几种方法
1.setSate, 2.props的改变 3.forceUpdate
//执行顺序
redner => componentDidUpdate
3.卸载时
componentWillUnmount
触发时机:组件卸载
作用:执行清理工作
4.其他钩子函数
shouldComponentUpdate
10.高阶组件
1.使用步骤
(1)创建一个函数,约定名称以width开头
(2)指定函数参数,参数应以大写字母开头(因为之后要作为组件渲染)
(3)在函数内部创建一个类组件,类组件实现复用逻辑,并返回该组件
(4)在该组件中,渲染参数组件,并通过props把该组件state传递给参数组件
(5)调用改高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,渲染到页面上
2.例子
// 高阶组件
import React from "react";
function widthMouse(WrappedComponent){
class NewMounse extends React.Component{
state = {
x:0,
y:0
}
handleMouseMove = e => {
this.setState({
x:e.clientX,
y:e.clientY
})
}
componentDidMount = () => {
window.addEventListener('mousemove', this.handleMouseMove)
}
render(){
//防止props丢失问题,这里面也将props传给参数组件
return <WrappedComponent {...this.state} {...this.props}>
</WrappedComponent>
}
}
return NewMounse
}
export default widthMouse
//参数组件
import React from "react";
class NewMounse extends React.Component{
render(){
return (
<div>
鼠标位置:{this.props.x}, {this.props.y}
</div>
)
}
}
export default NewMounse
//使用高阶组件在app.js文件中
import widthMouse from './components/HighMouse';
import NewMouse from './components/NewMouse'
class App extends React.Component{
render(){
const Com = widthMouse(NewMouse)
return(
<div class='app'>
<Com></Com>
</div>
)
}
}
11.setState详解
1.推荐语法
state ={
count:1
}
setState((state, props) => {
return {
count:state.count + 1
}
}, () => {
console.log(this.state.count) //2
}
)
console.log(this.state.count) //1
注意:此种语法更新变量也是异步的
2.setState方法的第二个参数
setState((state, props) => {
return {
count:state.count + 1
}
})
12.jsx语法的转化过程
1.jsx仅仅是createElement方法的语法糖及createElement的简化语法
2.jsx语法被 @babel/preset-react 插件编译为createElement()方法得到的对象
3.react元素是一个对象
13.组件的更新机制
更新机制:向下更新,更新当前组件及子组件,兄弟组件及父组件不会更新
14.组件优化
1.减轻state 保证state只存储和渲染相关的数据 其他与渲染无关的数据,需要多处使用的,存放在this中
15.React路由
1.路由的使用 (简单的使用步骤)
react-router-dom版本6.0.1
import { BrowserRouter as Router, Route, Link, Routes }
from 'react-router-dom';
return(
<Router>
<div className='App'>
<Link to='/child'>导航1</Link>
<Link to='child1'>导航2</Link>
<Routes>
<Route path="/child" element={<Child />}></Route>
<Route path="/child1" element={<Child1 />}></Route>
</Routes>
</div>
</Router>
)
react-router-dom版本6.0.1以下
import { BrowserRouter as Router, Route, Link}
from 'react-router-dom';
<Router>
<div className='App'>
<Link to='/child'>导航1</Link>
<Link to='child1'>导航2</Link>
<Routes>
<Route path="/child" component={Child}></Route>
<Route path="/child1" component={Child1}></Route>
</div>
</Router>
)