React基础 笔记

React基础 笔记,第1张

React特点 声明式组件化web,mobile,vr React安装

npm i react react-dom

react使用 引入


创建元素
// 名称,属性,之后子节点
const title = React.createElement('h1', null, 'hello react')
渲染
// 挂载元素,挂载位置
ReactDOM.render(title, document.getElementById('root'))
React脚手架

npx create-react-app my-app
npm start

React脚手架使用 ES6导入React.createElement()ReactDOM.render() JSX

直接使用声明式的HTML的标签
该语法为ECMA扩展语法,使用babel/preset-react编译后使用

语法规则

驼峰命名

class -> classNamefor -> htmlFortabindex -> tabIndex

无子节点标签可以 />结尾

推荐小括号包裹()

js嵌入js
// 使用 {}
const name = 'dog';
const = (hello,{name})
{} 注意点 {} 中可以输入js表达式{} 中可以调用函数jsx自身也可以放入{}不能直接使用object,一般只出现在style中不能出现语句 条件渲染、列表渲染

使用map进行列表渲染时需要加上key,渲染谁,key就加谁身上(避免使用索引作为key)

jsx样式处理 行内:style= { { color:‘red’} }类名:className 附

React完全使用js语言自身的能力来编写ui,而不是造轮子增强html功能

组件 组件创建 函数(无状态组件)

约定

首字母大写返回值&&表示组件结构
function Hello(){
  return 第一个函数组件
}
ReactDOM.render(, document.getElementById('root'))
类(有状态组件)

约定

首字母大写继承React.Component必须有render()方法且返回值为组件结构 抽离组件 创建组件.jsimport React from 'react'创建类export default ‘className’在使用的文件中import改组件 事件处理

on+event={事件处理程序}

function类型组件不需要this

state
组件类型名称功能
function无状态只负责展示
class有状态更新UI
state使用
// 1
constructor(){
  super()
  this.state={
    count:0
  }
}
// 2
state={
  count:0
}
修改state

不能直接修改

this.setState()

将事件处理抽离出render

此时this为undefined

this应该指向组件实例

事件绑定this指向 箭头函数
//函数要加()

Function.prototype.bind()
//在constructor内部将this绑定到方法上
this.myFunction = this.myFunction.bind(this);
class实例方法(推荐)
handleClick=()=>{
  this.setState(
    {count:this.state.count+1}
  )
}
表单处理 受控组件

将表单元素的value交给state去控制



handleChange=(e)=>{
    this.setState(
      {txt:e.target.value}
    )
  }
//处理多表单
//为表单元素添加name属性,name的值与state绑定的value一样
handleChange=(e)=>{
    const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
    const name = e.target.name
    this.setState(
      //属性名表达式??
      {[name]:value}
    )
  }
非受控组件

React.createRef()方法创建ref对象

this.txtRef = React.createRef();

添加ref属性

ref获取文本框的值

getText =()=> this.txtRef.current.value 表单联系出错事项 凡是使用this.state的地方必须使用{}包裹凡是使用html标签的地方要使用()包裹渲染数据需要加key属性到要遍历的节点上直接调用function要加(),事件处理程序不需要添加state数组方法 [{新数据},...原数据] 组件通讯 props

props

接收传递给组件的数据可以传递任何类型的值,包括function和jsx只读class组件中,构造函数中拿props需要super(props)

传递数据:组件标签添加属性
接收数据:

function(参数接收)class通过this.props 组件传值 父传子 子传父 父组件提供一个回调函数将函数作为属性传给子组件在子组件中将数据作为函数参数传递且调用在父组件中触发改回调函数 兄弟组件

状态提升,将state给最近的父组件

在父组件提供共享数据在父组件提供 *** 作方法 Context

跨组件传递数据

React.createContext();
// ??
// 创建context得到两个组件
const { Provider, Consumer } = React.createContext()
在两个传值组件中使用
// 传递

  
    我是1级
    
  


// 接收

  {
    data=>{data}
  }

props.children

jsx,function,components都可以作为子节点

子节点

props校验 props使用

创建组件时,指定props的类型

package: prop-types npm i prop-types
import PropTypes from 'prop-types'
//注意大小写
ComponentName.propTypes={
  color: PropTypes.array
}
props约束规则 类型elementisRequired特定结构对象:shape({}) props默认值
ComponentName.defaultProps={
  pageSize: 10
}
组件生命周期 创建(挂载阶段) Constructor() this指向state初始化 render() 组件渲染render中不能调用setState componentDidMount() DOM渲染后网络请求此时可以获取、 *** 作DOM 更新(更新阶段) rener() New propssetStateforceUpdate() componentDidUpdate(preProps) DOM重新渲染后在if语句中调用setState 卸载(卸载阶段) componentWillUnmount() 清理(定时器) 组件复用 render props render模式 使用组件时,添加一个值为函数的prop,通过参数来获取state
state={
  x:0,
  y:0
}
render(){
  return this.props.render(this.state)
}
componentDidMount(){
  window.addEventListener('mousemove',this.handleMousePos)
}
handleMousePos=(e)=>{
  this.setState({
    x:e.clientX,
    y:e.clientY
  })
}
使用函数的返回值作为渲染的UI内容
root.render((
当前位置:{data.x}:{data.y}
)}/>)
children模式

Context的用法和children一致
1.


  {mouse=>{return (当前位置:{mouse.x}:{mouse.y})}}

this.props.children(this.state)
添加render-props优化 校验
ComponentName.propTypes={
  children:PropTypes.func.isRequired
}
组件卸载时事件绑定
componentWillUnmount(){
  window.removeEventListener('mousemove')
}
HOC(高阶组件-函数)

//??
包装模式

使用 创建函数,约定以with开头指定参数,参数为组件因此大写字母开头在内部创建类组件,提供状态逻辑代码通过prop传递给参数组件
import React from 'react'

function withMouse(WrappedComponent){
  class MouseMove extends React.Component{
    state={
      x:0,
      y:0
    }
    componentDidMount(){
      window.addEventListener('mousemove',this.handleMouseMove)
    }
    handleMouseMove=(e)=>{
      this.setState({
        x:e.clientX,
        y:e.clientY
      })
    }
    componentWillUnmount(){
      window.removeEventListener('mousemove')
    }

    render(){
      return 
    }
  }
  return MouseMove
}

const Position = (props) =>(

鼠标当前位置:{props.x}:{props.y}

) const Don = withMouse(Position); class MyCom extends React.Component{ render(){ return ( 123456 ) } } export default MyCom
displayName

区分不同高阶组件名字

MouseMove.displayName = `WithMouse${getDisplayName(WrappedComponent)}`

function getDisplayName(componentName){
  return componentName.displayName|| componentName.name || 'Component'
}
props丢失
return 

子组件多次使用需要在外边包裹div

解构,将对象中的某些元素给暴露出来,直接使用获取0-2的随机数,Math.floor(Math.random()*3) 原理 setState 异步更新数据避免多次调用setState只触发一次render() 推荐语法
// state为最新state
// props为最新props
// 回调会在DOM重新更新后触发
this.setState((state,props)=>{
  return {
    num:state.num +1
  }
},()=>{})
JSX语法转化过程

JSX->preset-react->React.createElement()->React元素 Obj

组件更新机制

setState

修改state更新UI

只会更新当前组件以及子组件

组件性能优化 减轻state 之储存跟组件渲染有关的数据多个方法之间共享但和组件渲染无关的数据放入this中 避免不必要的重新渲染

更新阶段
shouldComponentUpdate->render

//false为不渲染该组件
// nextProps 最新props this.props当前props
// nextState 最新状态 this.state当前状态
shouldComponentUpdate(nextProps,nextState){
  return false
}
纯组件

React.PureComponent与React.Component类似,只是自动调用shouldComponentUpdate
分别比较前后两次的props和state来觉得是否需要重新渲染组件

通过shallow compare来进行判断
obj仅仅比较地址有没有变,因此不能直接copy该object

//创建新对象
const newObj = {...state.obj,number:2}
//数组
//不要使用push,unpush
//使用concat,slice
[...this.state.list,{newList}]
虚拟DOM和Diff算法

同组件相同,组件内不变的DOM是否需要更新

state(Model)->Virtual DOM->DOMsetState->new Virtual DOM->DOMdiff:compare Virtual(Virtual DOM,new Virtual DOM)render the changed part to the DOM

render之后
V-DOM -> JSX + State
性能,跨平台

路由 安装:yarn add react-router-domimport { BrowserRouter as Router,Route,Link,Routes} from ‘react-router-dom’
// 6版本以上

  
    路由配置规则
    页面去把
    
      }>
    
  

// 以下

//不需要Routes

注意 包裹整个应用 BrowserRouter/HashRouter

HashRouter:使用URL的哈希实现
BrowserRouter(推荐):使用H5的history API实现

Link

路由入口
页面去把
等同于
+ (location.pathname)

Route

路由入口

path 路由规则component 指定的组件Route 指定渲染位置 执行过程 点击Link标签,修改浏览器地址栏中的URLReact监听地址栏URL变化React路由内部遍历所有的Route组件,使用路由规则(path)和pathname匹配匹配成功展示该组件 编程式导航

JS代码实现页面跳转

// 跳转到指定路径
this.props.history.push('/path')
// 前进后退到第几个
this.props.history.go(n)
默认路由

}>

模糊匹配

path匹配

path:/ 可以匹配所有路由path:/first 可以匹配 pathname/to:/first//first/a/first/a/b/.. 精确匹配

path和pathname完全匹配才可以
给Route加上exact属性

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/928634.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存