React学习笔记

1.配置 Yarn

1.1 yarn的安装和报错解决

a .安装

npm install -g yarn

b. cmd中不是内部命令的解决

此电脑–> 高级系统设置–>环境变量–> 用户变量–> 找到yarn文件所在目录,不是bin目录

React学习笔记_第1张图片

c. yarn在powershell中运行失败的解决方法

1、到C:\Windows\System32\WindowsPowerShell\v1.0 目录下,右键选择以管理员身份运行powershell.exe
2、执行set-ExecutionPolicy RemoteSigned,选择Y就可以了

2. React

2.1. Create-react-app

npm install -g create-react-app   //安装react脚手架工具
create-react-app project          //创建react脚手架项目
//或者 npx create-react-app 项目名称
cd project                        //切换到项目文件夹
npm start                         //运行react项目

2.2 状态中的数据变动

ps:特别注意

  1. 不要直接修改

    禁止 this.state.time=new Date()`

  2. 不能直接更新

    禁止 let { comments } = this.state

    推荐 let comments = [ ...this.state.comments ]

2.3 React Ajax

2.3.1 前置说明

  1. React只关注界面,并不包含Ajax请求数据代码;

2)前端应用需要通过Ajax请求与后台进行数据交互;

  1. React应用中需要集成第三方Ajax库(或者自己封装);

2.3.2 常用Ajax请求库

1)jQuery:比较笨重,如果需要另外引入不建议使用;

2)Axios : 轻量级,建议使用,而且是promise风格的,可以解决回调地狱;

3)fetch : 原生函数,但是老版本的浏览器不支持,可以使用fetch.js,符合关注点分离;

4)fly : 微信小程序比较常用;

2.3.3 React 中的跨域解决方案

  1. 开发模式下:(书写代码模式)
    利用环境解决:React 和 Vue 框架都提供了解决方案
  2. 生产模式下:(打包上线模式)
    利用 jsonp 或者 cors 或者 postMessage 或者 iframe
  • 直接在 package.json 中配置 "proxy":"http://localhost:4000"
  • 或者下载 http-proxy-middleware 中间件进行解决
    npm install http-proxy-middleware --save
    or
    yarn add http-proxy-middleware

2.4 React-Css样式写法

export default class App extends React.Component{
     
    render(){
     
        return <div style={
     {
     width:"100px"}}> </div>
    }
}

2.4.1 动态添加类名

  1. 如果只需要添加一个类名

    <div className={
           index===this.state.currentIndex?"active":null}>此标签是否选中</div>
    
  2. 如果本身有其他的className,又需要添加其他的类名

    <div className={
           ["container tab", index===this.state.currentIndex?"active":null].join('空格')}>此标签是否选中</div>
    

    或者模板字符串

    <div className={
           `container tab ${
             index===this.state.currentIndex?"active":null}`}>此标签是否选中</div>
    

2.4.2 动态添加style样式

  1. 单个样式的写法

    <div style={
           {
           display: (index===this.state.currentIndex) ? "block" : "none"}}>此标签是否隐藏</div>
    
  2. 多个样式的写法

    此标签是否隐藏

2.5 组件通信 React-redux、props、发布订阅模式

2.5.1 pubsub-js 发布(publish)- 订阅(subscribe)模式

  1. 安装

    1)工具名称 :PubSub-js

    2)下载 npm install pubsub-js

  2. 使用方法Github详细地址

    // 引入的两种方法
    import PubSub from 'pubsub-js'
    // or when using CommonJS
    const PubSub = require('pubsub-js');
    
    //发布
    PubSub.publish('pubsub',data)//发布一个事件名称
    
    
    //订阅
    PubSub.subscribe('pubsub',function(msg,data){
           
    	//data是我们需要接收的数据,然后我们进行操作
        console.log(data)
    })
    
    1. 适用场景:任意组件之间通信;
    2. 缺点:没有集中式管理,比较乱;

2.5.2 使用props

​ 1)共同的数据需要放在父组件上,特有的数据放在自己的组件内部;

​ 2)通过props传递数据,需要一级一级的传递,特别的繁琐;

​ 3)一般属性–> 父组件传递数据给子组件–> 子组件读取数据;

​ 4) 函数属性–> 子组件传递数据给父组件–> 子组件调用函数;

​ 5) 适用场景:最好应用在父传子上面,子传子也可以;

2.5.3 获取封装组件标签之间的数据

//jsx 
<Button>点我进行跳转</Button>

//获取
console.log(this.props.children)

2.6 路由 React-Router

2.6.1 概念

组件是 React 的核心功能,其拥有非常强大的声明式编程模型。React Router导航组件的集合,可与你的应用程序进行声明式的组合。无论你是想为你的 Web 应用程序添加书签,还是在 React Native 中进行组件化导航,React Router 都可以在 React 的任何位置渲染使用 - 所以请考虑使用!

2.6.2 使用和安装

npm install react-router-dom

2.6.3 使用方法

2.6.4 路由切换去向

路由切换的时候,路由组件卸载了,可以在路由组件的生命周期componentWillUnmout周期中进行打印

2.6.5路由分类

  1. 后台路由:node服务器路由,value是function,用来处理客户端提交的请求并返回一个相应数据;
  • 注册路由:router.get(path,function(req,res){});
  • 当node接收到一个请求时,根据请求路径找到匹配的路由没吊用路由中的函数来处理请求,返回响应数据;
  1. 前端路由:浏览器路由,value是component,当请求路由path,浏览器端没有发送http请求,但是界面会更新显示对应的组件;
  • 注册路由:;
  • 当URL地址中的Hash变为/about时,当前的路由组件就会变为About组件;

2.6.6 前端路由的实现

  1. History 库
  • 网址 : https:/github.com/ReactTraining/history
  • 管理浏览器回话历史的工具库;
  • 包装的是原生的BOM中window.history和window.location.hash;

2)History API

​ a. History.createBrowserHistory():得到封装window.history的管理对象;

​ b. History.createHashHistory:得到封装window.location.hash的管理对象;

​ c.history.push() :添加一个新的历史记录;

​ d.history.replace():用于添加一个新的历史记录替换当前的记录;

​ e.history.goBack(): 回退到上一个历史记录;

​ f.history.foForward(): 前进道下一个历史记录;

​ g.history.listen(function(location){}): 见识历史记录的变化;

2.6.7 React-router 相关组件API

  1. //历史路由

  2. //hash路由

  3. //路由器 ,包裹的外壳

  4. // 路由 ,负责路由组件的切换

  5. // 路由重定向

  6. //普通 链接相当于a标签
  7. //附带动态切换的a 标签

  8. // 只匹配一个的组件

2.6.8 浏览器的历史记录

浏览器的历史记录,是栈结构,是一种数据结构

2.6.9 React-Router 路由跳转方法

  • 编程式路由跳转
//在路由组件中获取this.props
this.props.history.push()    //默认跳转,存在路由栈中
this.props.history.replace() //没有历史记录;
this.props.history.goBack()  //返回上一级页面
this.props.history.goWord()	 //前进一个页面
  • 标签式跳转
import {
     Link ,NavLink} from "react-router-dom";

<Link to="/url"></Link>
<NavLink to="/url"></NavLink>

3.Ant Design

@import '~antd/dist/antd.css';// ~ 在工程化、组件化中代表的是node_modules文件夹

3.1 按需引入 - 有以下两种方法

npm install babel-plugin-import --dev     // 安装按需引入插件,必须

3.1.1 eject拉取配置

​ a. 拉取配置之后,在page.json文件中添加如下代码;

React学习笔记_第2张图片

​ b. 书写完毕,然后直接引入插件,不必引入样式文件即可使用;

3.1.2 使用 react-app-rewired

  1. 安装react-app-rewired
npm install react-app-rewired --dev
  1. 修改package.json:
    /* package.json 的配置需要做如下修改*/
    "scripts": {
           
    -   "start": "react-scripts start",
    +   "start": "react-app-rewired start",
    -   "build": "react-scripts build",
    +   "build": "react-app-rewired build",
    -   "test": "react-scripts test --env=jsdom",
    +   "test": "react-app-rewired test --env=jsdom",
    }
    
  2. 然后在项目的根目录下创建一个 config-overrides.js 用于修改默认配置:
    const {
            override, fixBabelImports, addLessLoader } = require('customize-cra');
    
    module.exports = override(
      fixBabelImports('import', {
           
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: "css",
      }),
      addLessLoader({
           
        javascriptEnabled: true,
        modifyVars: {
            '@primary-color': '#ada57a' },
      })
    );
    
    
  3. 使用组件:
    import {
            Button } from 'antd';
    

3.2 自定义主题

3.2.1 下载软件包

npm install react-app-rewired customize-cra babel-plugin-import  //下载三个插件的安装包

react-app-rewired    //修改默认配置
customize-cra        //按需加载
babel-plugin-import	 //动态引入的

ps:使用[email protected] $ yarn add react-app-rewired customize-cra@next,否则自定义主题会报错

npm install react-app-rewired customize-cra@next babel-plugin-import  //下载三个插件的安装包
npm install less less-loader //安装less的相关配置

在项目的根目录创建config-overrides.js文件 ,然后改写config-overrides.js

const {
     override,fixBabelImports,addLessLoader}=require('customize-cra');
module.exports=override(
	flxBabelImports("import",
        {
     
            libraryName:"antd",
            liararyDirectory:"es",
            style:true,
        }
    ),
    addLessLoader({
     
        javascriptEnabled:"true",
        modifyVars:{
     "@primary-color":"yellow"}
    })
)

ps:注:如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。

4.高阶函数和高阶组件

概念:

高阶函数:一个函数接收 一个函数作为参数或者函数调用的返回值是一个函数

高阶组件:一个组件接收一个组件加工成一个新的组件,就叫做高阶组件。

5 原生Redux和React-redux

5.1 工作流程图

  • 原生Redux工作流程图

React学习笔记_第3张图片

  • react-redux工作流程图

React学习笔记_第4张图片

5.2 Redux 学习网站

​ 1)reudx 英文网

​ 2)redux 中文网

​ 3)github官网

5.3 redux的使用安装

//NPM
npm install redux
//或者
// Yarn
yarn add redux
5.3.1 Redux是什么?

1) redux是一个独立专门用于做状态管理的JS库(不是react插件库);

2)它可以用在React、Angular、Vue等项目中,但是基本上与React配合使用;

3)作用:集中式管理(读/写)React应用中多个组件共享的状态;

5.3.2 什么情况下需要使用Redux

1)总体原则:能不用就不用,如果不用比较吃力才考虑使用;

2)某个组件的状态,需要共享;

3)某个状态需要在热河地方都可以拿到;

4)一个组件需要改变全局状态;

5)一个组件需要改变另一个组件的状态;

5.3.3 Redux的核心API
  • createStore()

    1)作用:创建包含指定reducer的store对象;

    2)代码:

    import {
           createStore} from "redux"
    import counter from "./reducers/counter" 
    
    const store=createStore(counter)
    
  • store 对象

    1) 作用:redux库最核心的管理对象,它的内部维护这state、reducer

    2)核心方法:dispatch(action)、getState()、subscribe();

    1. 编码:
    store.getState()           //获取数据
    store.dispatch(action)	   //派发动作
    store.subscribe(callback)  //检测store的改变并重新渲染页面
    

5.2 React-redux

5.2.1 概念

​ 1) 一个react的插件库;

​ 2)专门用于简化在react应用中使用redux;

5.2.2 安装

npm install --save react-redux

5.2.3 React-redux 将所有组件分成两大类

1)UI组件

  • 只负责UI的呈现,不带有任何的业务逻辑;
  • 通过props接受数据(一般数据和函数);
  • 不适用任何Redux的API;
  • 一般保存在components文件夹下;

2)容器组件

  • 负责管理数据和业务逻辑,不负责UI的呈现;
  • 使用Redux的API;
  • 一般保存在containers文件下;

5.2.4 相关API

  • provider

所有组件都可以得到state数

<Provider store={
     store}>
    <App/>
 </Provider>
  • connect()

用于包装UI组件生成器组件

import {
      connnect } from "react-readux";
connect(
	mapStateToProps,
    mapDispatchToProps
)(Counter)

connect()精简写法

connect(
	state = > ({
     count:state}),
    //mapDispatchToProps 精简写法
	{
     
		increment:incrementAction,
    	decrement:decrementAction
    }
)
  • mapStateToprops()

将外部的数据(及state对象)装换为UI组件的标签属性

const mapStateToprops=function(state){
     
    return {
     
        value:state
    }
}
  • mapDispatchToProps()

将分发action的函数转换为UI组件的标签属性,简洁语法可以直接指定actions对象或包含多个action方法的对象

5.3 异步React-redux

5.3.1下载redux插件(异步中间件)

npm install --save redux-thunk

5.3.2 修改store.js

import {
      createStore, applyMiddleware } from 'redux';
import {
      operationCount } from './reducers';
import thunk from 'redux-thunk';

//执行一个middle中间件

export default createStore(operationCount, applyMiddleware(thunk));

5.3.3 修改creators文件夹下面的action_creator.js

//分发一个异步action
export const incrementCreatorAsync = (data, delay) => {
     
  return (dispatch) => {
     
    setTimeout(() => {
     
      dispatch(incrementCreator(data));
    }, delay);
  };
};

5.4 redux-devTools调试工具

5.4.1 安装

npm install redux-devtools-extension --save-dev

5.4.2 使用

在store.js文件中引入,然后改写store.js文件

import {
      composeWithDeVTools } from "redux-devTools-extension";
export default createStore(reducer,composeWithDevWith(applyMiddleware(thunk)))

6.Diff算法

6.1 文档碎片

  1. 原理

使用原生js对象的文档碎片(fragment)的功能

  1. 作用

将需要添加的大量元素 先添加到文档碎片中,再将文档碎片添加到需要插入的位置,大大 减少dom操作,提高性能(IE和火狐比较明显)

6.2 Diff算法的使用

  1. .React和Vue中的key值得作用

key是虚拟Dom对象的标识,在更新显示时,有着重要的作用,当数据发生改变时,React会生成新的虚拟Dom,随后React将之前的旧虚拟Dom和新的虚拟Dom进行比较

​ a. 旧的虚拟Dom中找到了与新的虚拟Dom中相同的key

​ – 若虚拟Dom没有发生改变,直接使用原来的真实Dom,不去刷新页面;

​ – 若虚拟Dom发生了改变,先更新虚拟Dom,随后刷新页面的真实Dom;

b.旧的虚拟Dom中没有找到相同的key

​ – 根据数据创建新的虚拟Dom,随后渲染真实Dom到页面;

2).使用index索引作为key值得问题

  • 添加删除排序会产生不必要的真实Dom更新,界面效果可能没有问题,但是效率比较低

  • 如果真实Dom元素有输入框或者多选框等,会产生错误的真实Dom更新、

  • ps:如果不存在添加删除和排序则使用index索引作为key值是没有问题的

3).key值得解决方案

使用数据中对象中的id唯一标识

7.React基础

7.1 setState 是同步还是异步的

  1. setState 必然会引起页面的重绘
  2. 在可控的情况下是异步的,在不可控的情况下是同步的

7.2 key 的作用

  1. key 帮助 react 识别元素的改变,一个元素的 key 值最好在上下文中是独一无二的;

7.3 表单

  1. 受控组件
  2. 非受控组件

7.4 Refs 和 Dom 的使用

  1. 管理焦点,文本选择和媒体播放
  2. 触发强制动画
  3. 集成第三方的 Dom 库

正常情况下推荐使用受控组件,除非input输入框的存在特别多的情况下,才会去考虑使用非受控组件

Ref的三种使用方式

  1. 字符串的使用方式 this.refs.input (使用最多的情况)

  2. 回调函数的使用方式 (炫技的情况)

    (this.input=input)}>

  3. createRef API的使用 (最恶心的使用情况)

    myRef=React.createRef()

    //获取方式
    this.myRef.current.value
    

7.5 状态提升

  1. 组件之间的数据交互

7.5.1 组合 vs 继承

this.props.children

7.5.2 使用 propsType 进行类型检查

7.6 生命周期图谱

  1. 移除

    componentWillMountcomponentWillReceiveProps将要被移除,这被官网认为是不安全的。如果使用的话,需要在方法前面添加 UNSAFE_ ,例如UNSAFE_componentWillMount()

  2. 生命周期(新)最新更新

React学习笔记_第5张图片
  1. **getDerivedStateFromProps ** 用于取代:componentWillMountcomponentWillUpdate

  2. getSnapshotBeforeUpdate 介于rendercomponentDidUpdate之间,而且必须和componentDidUpdate配合使用,几乎不会被使用;此生命周期的任何返回值将作为参数传递给 componentDidUpdate(),此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。

    应返回 snapshot 的值(或 null)。

  3. 更新的过程

  • static getDerivedStateFromProps() //初始化渲染
  • shouldComponentUpdate() //是否需要更新
  • render() // 渲染
  • getSnapshotBeforeUpdate() // 介于render和componentDidUpdate方法之间
  • componentDidUpdate() // 更新结束

你可能感兴趣的:(react,reactjs,大前端,javascript,html)