React内容

React Fiber   16版本

 

registerServiceWorker 的作用  

PWA  progressive web application  写手机app应用   在断网的情况下,第二次访问会缓存

 

ReactDOM.render 会把组件挂载到真实DOM节点上

JSX语法   js里面写html + 自定义组件(自定义组件名称必须大写)

 bind(this,  index) 可以在bind里面传递参数

 

list.splice(index, 1) 删除一项

state 不允许直接做任何改变     不要 this.state.list.splice(index, 1)

 

解析 html  可能存在XSS攻击

<li  dangerouslySetInnerHTML = {{ __html:item }}>

 

 label扩大点击区域

<label  htmlFor="inputa">输入内容</label>

<input id="inputa"/>

 

render 返回的内容  注释和其他部分不能是同一级别

不允许在子节点中直接修改父组件中的state

样式引入放在最后面

 

this.setState((prevState)=>{
 return {value:e.target.value} // 需要提前获取value
})  否则可能会有问题

直接操作DOM, 是命令式编程, 大部分都在进行DOM操作

声明式编码  数据驱动 

 

单向数据流:父组件传值给子组件  子组件只能使用而不能改变

否则会报错 

好处是不容易出错, 因为可能在多个子组件中修改父组件的数据,可能导致出错

 

函数式编程给测试带来了便捷 

复制代码
propTypes和defaultProps

import PropTypes from 'prop-types';

// 规定类型
TodoItem.propTypes = {
    test:PropTypes.string.isRequired,
    content: PropTypes.string,
    handItem: PropTypes.func,
    idx: PropTypes.number
}

// 默认值
TodoItem.defaultProps = {
    test:"hello,world"
}
复制代码
PropTypes.arrayOf(string,number) 数组的内容类型
oneOfType([string,number]) 才是 多种类型的一种

 

props state 与 render函数的关系

当组件的state或者 props发生变化的时候 render方法重新直接

当组件的render方法被执行时,它的子组件的render方法也会被执行

 

生成DOM替换原来的DOM都会非常消耗性能

一点点改变  都会导致新DOM的生成

 

改变:新生成的DOM和原来的DOM做对比找差异

只替换改变的DOM部分

 

缺陷:性能提升并不明显

 

改进:生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实DOM)

<div id=’abc’>aaa</div>
React.createElement(“div”, {id:’abc’}, abc)

数据发生了改变,生成新的 虚拟DOM

然后和原来的 虚拟DOM做对比

通过diff算法,找到不同的部分,然后直接操作DOM替换改变的部分

 

js生成一个js对象代价小,但是生成一个DOM代价高

只要和DOM相关的操作都极大消耗性能(不管是比较还是生成)

用虚拟DOM的结构生成真实DOM

 

jsx --> createElement 方法 --> 生成虚拟DOM(js对象) --> 真实DOM

该方法偏向底层  和<div>aaa</div> 效果是一样的  只是这么写比较简便

 

jsx 语法并不是真实的DOM,只是一个模板

所以就算没有jsx语法 也可以通过 createElement来替代

 

虚拟DOM生成在前 真实DOM生成在后

虚拟DOM的好处:

1.性能提升了

2.它使得跨端应用得以实现 (虚拟DOM 并不生成真实DOM) 而生成原生应用的组件

 

 Diff算法   对比虚拟DOM (js对象)

1. 同级比对 + key 值比对

如果一致  继续比对第二层

如果不一致 则不再进行下一层的比对

 

好处是:比对算法比较简单

 

为什么setState 要设计成异步函数

多次短时间的操作可以合并成一次操作   减少对比虚拟DOM的次数

 

循环的时候 key的意义   比对和 key 值做关联

为什么key值 不要设置为 index

因为插入数组元素的时候   div 的index可能 改变成其他div的index

导致 key值不稳定  就失去了存在的意义

 

react中ref的使用

<input  ref={ inp=> this.inp = inp }>

在使用的时候,直接使用 this.inp即可

不推荐使用ref 

注意:ref和setState一起使用的时候可能导致结果不正确

因为setState 是异步的

 

this.setState((prevState)=>{}, ()=>{})  第二个参数的意思是setState 执行完成之后,执行某些操作

这样就可以保证在更新完数据以后正确的执行某些操作

 

声明周期函数:

componentWillReceiveProps(props)

当一个组件从父组件接受参数  ==>  执行的时机

只要父组件的render函数重新被执行了,子组件的render函数也会被执行

换个说法

如果这个组件第一次存在组件中,不会被执行

如果这个组件之前已经存在于父组件中,才会被执行

当一个组件是父组件没有props值就不会被执行

 

shouldComponentUpdate 返回 bool

 

只会执行一次

componentWillMount / componentDidMount / componentWillUnmount

 

生命周期函数的使用场景

1. input 值改变,就会导致state改变 页面重新渲染

浪费了性能 使用shouldComponentUpdate

shouldComponentUpdate(nextProps,nxtState){
   return nextProps.content !== this.props.content? true:false;
}

 

在发送ajax请求的时候, 不能放在render方法中,因为render可能会被反复执行

componentDidMount 最好

componentWillMount 可能和react native 有冲突 

 

使用Charles进行接口数据模拟
componentDidMount(){
        axios.get('/api/todoList')
            .then((res)=>{
                this.setState(()=>({list:[...res.data]}));
tools – map local 
复制代码
css过渡动画
render(){
        return <Fragment>
            <div className={ this.state.isShow? "show":"hide"}>hello,React</div>
            <button onClick={ this.handlerClick }>toogle</button>
        </Fragment>
    }

.show {
    opacity: 1;
    transition: all 1s ease-in;
}

.hide{
    opacity: 0;
    transition: all 1s ease-in;
}
复制代码

 

复制代码
动画效果 通过@keyframes来定义动画
.hide{
    animation: hide-item 2s ease-in forwards;
}   加上forwards的作用是 保存动画最后一帧的CSS样式

@keyframes hide-item{
    0%{
        opacity: 1;
        color: red;
    }
    50%{
        opacity: 0.5;
        color: green;
    }
    100%{
        opacity: 0;
        color: blue;
    }
}
入场也是一样   反过来就可以了
复制代码

 

使用react-transition-group 实现动画  yarn add

 

 

redux基础

组件树复杂的时候,组件传值非常麻烦

数据放在公共区域,而不是放在组件上

直接改变store里面的数据,组件就会自动感知到

 

Redux = Reducer + Flux

react是和Flux一起放出来的  Flux不是特别好用

Reducers 记录本

 

Component --> ActionCreators --> store --> Reducers --> Store --> Components 

 

constructor(props){
        super(props);
        this.state = store.getState();
    }

 

reducer的限制: reducer可以接收 state,但是绝对不要修改 state

newState 返回给了 Store

 

store.subscribe(()=>{this.setState(store.getState())
}) 这个组件去订阅store
复制代码
handlerChange(e){
        const action  = {
            type: 'change_input_value', 
            value: e.target.value
        };
        store.dispatch(action); //将action传递给 store
    }  然后store就会自动把 action转发给reducer

if(action.type === 'change_input_value'){
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputVal = action.value;
        return newState;
    }
复制代码

 return 返回回来的数据 就会给 store 然后store替换原来的数据

 

UI组件和容器组件的拆分

ui组件页面的渲染  傻   只管页面  不管逻辑

容器组件   聪明   不管页面  只管逻辑

 

无状态组件性能比较高, 它就是一个函数

而普通组件要执行一些生命周期函数

可以用于UI组件中

 

Redux 设计和使用的三大原则

1.store是唯一的  只有改变store能够改变自己的内容 

2. reducer是纯函数 (固定的输入差生固定的输出, 没有副作用)

所以里面不能有异步操作和时间相关的操作

例如: newState.date = new Date()   或者对参数直接进行修改  state.inputValue = action.value

 

是store拿到reducer返回的数据  然后store来进行更新

而不是reducer改版数据的  这也是为什么reducer一定不要直接改变store里面的数据

 

redux 中发送异步请求获取数据  放在组件的componentDidMount

使用redux-thunk 把异步的代码从组件的DidMount 中移除到action里面去

 

复制代码
const composeEnhancers =
  typeof window === 'object' &&
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;

const enhancer = composeEnhancers(
    applyMiddleware(thunk,…),
    );

const store = createStore(reducer,enhancer);
复制代码
componentDidMount(){
    const action = getInitData();//返回的是一个函数
store.dispatch(action); // 这一步就会发异步请求
   当返现action是一个函数,那么就会执行一下这个函数
}
componentDidMount(){
    const action = getInitData();//返回的是一个函数
    store.dispatch(action); // 这一步就会发异步请求
   当返现action是一个函数,那么就会执行一下这个函数
}

 

如果把异步请求的方法都放在组件的生命周期函数里面, 那么内容会越来越多,而且更加方便测试(测试函数比测试生命周期函数简单)

 

redux的中间件

中间指的是 action 和store的中间  只是对dispatch的升级

 

reset.css 加入到全局样式中去,在不同的内核上 不同的 标签的表现形式可能不同

 

background-size: contain  表示让图片包含在div中  正常大小

 

react只兼容到 IE8 

 

create-react-app 有一个特性  在public下面 定义api目录 可以当做 请求地址模拟后端请求访问

render 方法 可以返回一个数组 和字符串

 

React16.4 中废弃了一些生命周期函数

componentWillUpdate   componentWillReceiveProps

 

res.send / res.json / res.sendfile 响应不同的内容

 

回到顶部功能

window.scrollTo(0,0)

 

每一个组件都调用了 connect方法 和store进行了连接,只要每一个数据发生了改变

那么每一个组件都会被重新渲染   这样不好 例如 input框里面的数据改变

 

性能很低: 

在组件里面 都加上 componnentWillUpdate()  只要和自己相关的数据  就会返回 true 无关的就会返回false

将继承Component 都改为PureComponent  用了该组件就需要使用 immutable来管理数据 否则会出现坑

 

页面的跳转不要使用 a 标签  会加载 html  会消耗性能

import { Link } from ‘react-router-dom’
<Link to = ‘/detail’>

 

获取路由参数
<Link to=”/detail/:id”>
<Link to={ “/detail/” + “abc”>
<Route path=”/detail/:id”>

 

第二种方式
<Link to={ “/detail?id=” + “abc”>
<Route path=”/detail”>
这样就可以匹配到了
this.props.location.search  还要自己去解析这个字符串

 

styled-component 要通过 innerRef 得到原始的DOM结构

 

异步组件  yarn add react-loadable  

 

第一个参数是要加载的组件  第二个参数是加载过程中显示的组件

 

axios 拦截器

 

在使用express中使用 cookie  依赖 cookie-parse

 

 1. swiper loop 设为 true 时,同时有改变了 slidePreview 的值,这时轮播时,按prev按钮到第一个时

会出现空白页          解决办法: slidePrerview 设置为 auto  loopSliders 设置为你要显示的 slide个数

2. swiper-slide 为动态添加的内容 时  swiper的滑动效果会消失   

解决办法: 初始化中设置 observer 为true observerParent 为true

 

componentDidCatch(error, errorInfo){}  出错的生命周期函数

 

posted @   escapist  阅读(208)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示