React进阶学习

一、React进阶

1、React脚手架

npx create-react-app my-app

2、react

const React = {
	createElement,
	Component
}

React.createElement: 创建虚拟DOM
React.Component: 实现自定义组件

3、react-dom

主要是render逻辑。

ReactDOM.render: 渲染真实DOM

4、Redux

在这里插入图片描述

5、组件通讯

props

使用:函数组件通过props接收数据,类组件通过this.props接收数据。
特点:传递任意类型的数据;props是只读的对象;

props深入
  • children属性
  • props校验
Mouse.propTypes = {
	children: PropTypes.func.isRequired
}
  • props默认值
Mouse.defaultProps = {
	children: ""
}
三种方式
  1. 父传子
  2. 子传父
    通过回调函数实现
class Parent extends React.Component{
	getMsgCallback = data=>{
		console.log(data)
	}
	render(){
		return (
			<div>
				<Child getMsgCallback={this.getMsgCallback}>
			</div>
		)
	}
}

class Child extends React.Component{
	handleClick= ()=>{
		this.props.getMsgCallback("子传父") 
	}
	render(){
		return (
			<div>
				<button onClick={this.handleClick}/>
			</div>
		)
	}
}
  1. 兄弟组件
    状态提升
    在这里插入图片描述
Context

跨组件传递数据

const {Provider,Consumer}=React.createContext()

<Provider value="">
</Provider>

<Consumer>
{data => {}}
</Consumer>

6、组件的生命周期

  • 只有类组件才有生命周期
  • 不能在render钩子函数中调用setState函数
  • 在componentDidUpdate钩子函数中调用setState函数,要比较更新前后的状态是否相同

常用钩子函数:
在这里插入图片描述
旧版钩子函数:
在这里插入图片描述
新版钩子函数:
在这里插入图片描述

7、render props模式

实现状态逻辑复用,状态指的是state,逻辑指的是setState。

class Mouse extends React.Component{
	render(){
		return this.props.render(this.state)
	}
}

<Mouse render={(mouse)=><p>鼠标当前位置{mouse.x},{mouse.y}</p>}/>

children代替render属性

class Mouse extends React.Component{
	render(){
		return this.props.children(this.state)
	}
}

<Mouse>
{(mouse)=><p>鼠标当前位置{mouse.x},{mouse.y}</p>}
</Mouse>

添加props校验

import PropTypes from 'prop-types'

Mouse.propTypes = {
	children: PropTypes.func.isRequired
}

8、高阶组件

高阶组件之于组件相当于手机壳之于手机。

  • 目的:实现状态逻辑复用
  • 装饰模式
  • HOC,实际上是一个函数
const EnhancedComponent = withHOC(WrappedComponent)
function withMouse(WrappedComponent){
	class Mouse extends React.Component{
		return <WrappedComponent {...this.state}/>
	}
	return Mouse
}

const MousePosition = withMouse(Position)

<MousePosition/>
问题1

得到两个组件名称相同

解决1

设置displayName能在调试时区分不同组件

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

function getDisplayName(WrappedComponent){
	return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}
问题2

props丢失

解决2
<WrappedComponent {...this.state} {...this.props}/>

二、React原理

1、setState函数

作用:修改state;更新组件
注意:
异步更新数据;
多次调用setState函数只触发一次重新渲染;
setState(updater[,callback]),第二个参数在状态更新且页面完成渲染后立即执行某个操作;

// 经典写法
this.setState({
	count: this.state.count+1
})

// 推荐写法,多次调用setState函数的顺序更符合人类的思维顺序
this.setState((state,props)=>{
	return {
		count: state.count+1
	}
})

2、JSX语法的转化过程

JSX是createElement函数的简化语法。
JSX语法被@babel/preset-react插件编译为creatElement函数。
React元素:描述看到的内容。
在这里插入图片描述
JSX和JSX预处理后的代码:
在这里插入图片描述

3、组件更新机制

在这里插入图片描述

4、组件性能优化

减轻state

只存储与渲染相关的数据

避免不必要的渲染

使用钩子函数shouldComponentUpdate(nextProps, nextState)

纯组件

自动实现了shouldComponentUpdate钩子函数;
使用浅层对比,对于引用类型,只比较对象的地址;

const newObj = {...state.obj, number: 2}
setState({obj: newObj})

this.setState({
	list: [...this.state.list, {新数据}]
})

5、React的部分更新

实现:虚拟DOM配合Diff算法
虚拟DOM:React元素,本质是JS对象,描述UI。用JS对象表示DOM信息和结构,当状态变更的时候,重新渲染这个JS的对象结构

const element={
	type: 'h1',
	props: {
		className: 'greeting',
		children: 'Hello JSX'
	}
}

Diff过程:
在这里插入图片描述

三、React路由

  • 功能:从一个视图导航到另一个视图
  • 使用:配置路由和组件
  • 常用组件:
    Router组件,推荐用HistoryRouter
    Link组件
    Route组件,能够指定路由组件的位置
  • 路由的执行过程:
    在这里插入图片描述
  • 编程式导航
    通过JS代码实现页面跳转
    push(path)
    go(n)
  • 匹配模式
    • 模糊匹配
      默认匹配模式,pathname以path开头就匹配成功,pathname是Link组件的to,path是Route组件的path
    • 精确匹配
      添加exact属性
<Route exact path="/" component=... />

四、租房移动Web实践

核心业务

在线找房、用户登陆、房源发布

技术栈

React核心库:react、react-dom、react-router-dom
脚手架:create-react-app
数据请求:axios
UI组件库:antd-mobile
其他组件库:react-virtualized、formik+yup、react-spring
百度地图API

node-sass依赖

注意node-sass依赖的问题,多次yarn操作后可以成功安装,但默认情况下node-sass的版本与node的版本不一致。(着实纳闷)

condition:

node -v v14.17.3 
node-gyp -v v3.8.0

target:

yarn add node-sass@4.12.0

problem:

gyp verb `which` failed Error: not found: python2

solution:

yarn add global production windows-build-tools

H5的地理位置API

  • 获取的地理位置与GPS、IP地址、WIFI和蓝牙的MAC地址、GSM/CDMS的ID有关。手机优先使用GPS定位,笔记本最准确的定位是WIFI。
  • 只能获得经纬度信息。
navigator.geolocation.getCurrentPosition(position => {
  console.log('当前位置信息:', position)
})

百度地图API

使用步骤:

  • 引入百度地图API的JS文件,替换自己的密钥
  • 在index.css设置全局样式
  • 创建Map组件,配置路由。在Map组件中,创建地图容器元素,并设置样式
  • 创建地图实例
  • 设置中心点坐标
  • 初始化地图,并设置展示级别

地图找房

  • 百度地图标注
    文本覆盖物label
  • 缩放级别
  • 缩放事件

组件间样式覆盖问题

solution
  • 手动处理,定义不同类名
  • CSS IN JS
    • CSS Modules,React脚手架已集成
      说明:对CSS类名重命名,保证每个类名的唯一性。所有类名都有局部作用域。
      实现:webpack的css-loader
      命名:BEM规范(Block块、Element元素、Modifier)
      React脚手架中的命名:文件名、类名、hash
    • styled-components
案例

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值