IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React 的生命周期、组建通信及非受控组件(二) -> 正文阅读

[JavaScript知识库]React 的生命周期、组建通信及非受控组件(二)

一、前言及补充内容

????????昨天学习了 初识、构建以及 React 事件的基本用法和一些注意点,我们大概也掌握了 React 框架的语法. 当然其中也落下了几个问题,我就统一放到这篇文章来处理了.

1. 项目的启动报错问题(三种解决方案)

????????昨天在创建完项目之后,运行也是报了错误,困扰了很久,最终找到了这些方法,并且全部可行,希望对你们有所帮助

  1. 运行的项目路径不对 cd 到创建的项目路径,再运行

恩… 这个,不要小瞧这个错误,在你某些时候分心,忘了或者看别人自动化构建项目运行时,一味的执行命令,却忘了创建完项目,需要 cd 到指定项目文件夹.那样肯定会报错.这个问题,我昨天也碰到过了,第一次创建运行对于新手还是特别需要注意的

正确的步骤:
安装 React 框架 : npm i -g create-react-app
创建项目 : create-react-app 项目名称 (项目名称避免使用中文)
进入创建的项目路径 : cd 项目名字
运行项目 (如果这里运行出错,请看下面解决方案) : npm start

2. 缺少依赖

????????我们创建完项目之后,会在 package.json 配置中的 script 中看到以下代码

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

eact-scripts是create-react-app中的一个核心包一些脚本和工具的默认配置都集成在里面,执行命令 npm run eject 会复制所有依赖文件和相应的依赖(webpack、babel等)到你的项目。是个单向的操作,一旦 eject ,npm run eject的操作是不可逆的

正确的步骤 :
在你创建完项目之后,运行报错,就 输入复制依赖命令 : npm run eject
然后再运行项目 : npm run start

3. webpack 版本不同

????????第三种方法,在昨天的博客中用到了这种方法,并下载了这张图,让你明白具体是怎么回事

为了解决这个 webpack 版本不同的问题,我们在 src 同级目录下创建 .env 文件夹,然后放入一下代码,就可以解决

SKIP_PREFLIGHT_CHECK=true

2. 无法获取 this 值

????????在js中class的方法默认不会绑定this,必须使用this.handleClick并把他传入onClick,否则调用函数时this的值为undefined。解决绑定this的三种方法:

????????1. 构造函数绑定this(推荐)

class Button extends React.Component {
 
constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
 
  handleClick(){
    console.log('this is:', this);
  }
 
  render() {
 
    return (
      <button onClick={this.handleClick}>点我</button>
    );
  }
}

????????2. 调用的时候绑定this

class Button extends React.Component {
 
  handleClick(){
    console.log('this is:', this);
  }
 
  render() {
 
    return (
      <button onClick={this.handleClick.bind(this)}>点我</button>
    );
  }
}

????????3. 箭头函数:箭头函数中的this只会固定的指向声明时的this指向

return (
      <button onClick={() => this.handleClick()}>点我</button>
    );

3. babel 配置

????????我的 babel 配置是在一篇博客上学习的,这里就不在一 一介绍了,你们可以前去他的博客查看学习

网址 : babel 配置教学网址

二、React 父传子

  1. 父组件提供要传递的state数据
  2. 给子组件标签添加属性,值为state中的数据
  3. 子组件通过props接收父组件中传递的数据

????????代码实例 :

// 父组件
class Parent extends React.Component{
  state={
    lastName:"张三"
  }

  render(){
    return (
      <div className="parent">
        父组件:<Child name={this.state.lastName}/>
      </div>
    )
  }
}

// 子组件
const Child = (props)=>{
  console.log(props)
  return (
    <div className="child">
      <p>子组件,接收到父组件的数据: {props.name}</p>
    </div>
  )
}

????????运行后查看浏览器 :
在这里插入图片描述

三、React 子传父

  1. 父组件提供一个回调函数(用于接收数据)
  2. 将该函数作为属性的值,传递给子组件
  3. 子组件通过 props 调用回调函数
  4. 将子组件的数据作为参数传递给回调函数

????????代码实例 :

// 父组件
class Parent extends React.Component{

  state = {
    parentMsg:""
  }

  // 提供回调函数,用来接收数据
  getChildMsg = data =>{
    console.log("我收到了子组件中传递过来的数据 :" ,data)

    this.setState({
      parentMsg:data 
    })
  }
  render(){
    return (
      <div className="parent">
        父组件: {this.state.parentMsg}
        <Child getMsg={this.getChildMsg}/>
      </div>
    )
  }
}

// 子组件
class Child extends React.Component{
  state = {
    msg:"下大雨了"
  }

  handleClick = () =>{
    // 子组件调用父组件中传递过来的回调函数
    this.props.getMsg(this.state.msg)
  }
  render(){  
    return (
      <div className="child">
        子组件: <button onClick={this.handleClick}>点我,给父组件传递数据</button>
      </div>
    )
  }
  
}

????????运行后查看浏览器 :
在这里插入图片描述

四、组件通讯

????????将共享状态提升到最近的公共父组件中,由公共组件管理这个状态

公共组件职责 : 1. 提供共享状态 2. 提供操作共享状态的方法
要通讯的子组件 : 只需通过 props 接收状态或操作状态的方法

????????代码实例 :

// 父组件
class Counter extends React.Component{
  // 提供共享状态
  state = {
    count:0
  }

  // 提供修改状态的方法
  xiugai = () =>{
    this.setState({
      count:this.state.count + 1
    })
  }
  render(){
    return (
      <div>
        <Child count={this.state.count}/>
        <Child2 xiugai={this.xiugai}/>
      </div>
    )
  }
}

const Child = (props) =>{
  return <h1>计算器 : {props.count}</h1>
}

const Child2 = (props) =>{
  return <button onClick={()=>props.xiugai()}>+1</button>
}

????????运行后查看浏览器 :
在这里插入图片描述

五、生命周期

1. 组件生命周期概述

????????意义 : 组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等
????????组件的生命周期 : 组件从被创建到挂载页面中运行,再到组件不用时卸载的过程
????????生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数
????????钩子函数的作用 : 为开发人员在不同阶段操作组件提供了时机

2. 生命周期的三个状态

Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM

3. 挂载卸载过程

????????constructor

constructor完成数据的初始化,接受2个参数:props和content,当想在函数内部使用这两个参数,就必须使用super()传入这两个参数
注意:只要使用constructor就必须写super,否则会导致this的指向错误

????????componentWillMount

componentWillMount一般用的比较少,它更多的时在服务端渲染时使用,当前周期代表的时组件已经经历过constructor初始化数据后,但是还未渲染DOM的时候

????????compontntDidMount

组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染

????????componentWillUnmount

这个周期完成组件的卸载和数据的销毁
清除定时器
移除事件监听addEventListener

4. 更新过程

????????componentWillReceiveProps(nextProps)

接收父组件改变后的props
接收一个参数nextProps
对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染

????????shouldComponentUpdate(nextProps, nextState)

主要用于性能优化
可以控制组件的重新渲染的生命周期,因为在react中,setState后,state发生变化,组件重新渲染,这个周期可以return false来阻止组件的更新
父组件的重新渲染会导致其子组件的重新渲染,这个时候我们是不需要所有的子组件都重新渲染,所以在子组件的shouldComponentUpdate中做判断

????????componentWillUpdate(nextProps, nextState)

shouldComponentUpdate返回true以后,组件进行重新渲染的过程,在这个周期同样可以拿到nexeProps和nextState

????????componentDidUpdate(prevProps,prevState)

组件更新完毕后,react在componentDidMount之后,每次重新渲染都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state

????????render

这个周期react会生成一份虚拟DOM树,每次组件更新时,react会通过diff算法比较新旧DOM树,找到最小差异的DOM节点,重新渲染

4. 生命周期图解

在这里插入图片描述

六、受控组件

<input
    type="text"
    value={this.state.value}
    onChange={(e) => {
        this.setState({
            value: e.target.value.toUpperCase(),
        });
    }}
/>

????????受控组件要绑定一个change事件;每当表单的状态发生变化,都会被写入组件的state中,这种组件在React中被称为受控组件;在受控组件中,组件渲染出的状态与它的value或者checked prop向对应.react通过这种方式消除了组件的局部状态,是的应用的整个状态可控.

????????React受控组件更新state的流程:

1.可以通过初始state中设置表单的默认值;
2.每当表单的值发生变化时,调用onChange事件处理器;
3.事件处理器通过合成事件对象e拿到改变后的状态,并更新应用的state.
4.setState触发视图的重新渲染,完成表单组件值得更新

react中数据是单向流动的.从示例中,我们能看出来表单的数据来源于组件的state,并通过props传入,这也称为单向数据绑定.然后,我们又通过onChange事件处理器将新的表单数据写回到state,完成了双向数据绑定.

七、非受控组件

import React, { Component } from 'react';

class UnControlled extends Component {
    handleSubmit = (e) => {
        console.log(e);
        e.preventDefault();
        console.log(this.name.value);
    }
    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <input type="text" ref={i => this.name = i} defaultValue="BeiJing" />
                <button type="submit">Submit</button>
            </form>
        );
    }
}

export default UnControlled;

如果一个表单组件没有value props(单选按钮和复选按钮对应的是 checked props)时,就可以称为非受控组件;

使用defaultValue和defaultChecked来表示组件的默认状态;
通过 defaultValue和defaultChecked来设置组件的默认值,它仅会被渲染一次,在后续的渲染时并不起作用

八、总结

????????今日这篇博客补充解决了昨天落下的问题,也新学习了组件之间进行通讯、生命周期、受控组件以及非受控组件. 也学习到了新的编程思维语法.今天的学习到此结束,希望对你们有所帮助.我们下期见!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 13:24:52  更:2021-07-28 13:25:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/19 15:55:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码