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学习笔记2021.10.10 -> 正文阅读

[JavaScript知识库]React学习笔记2021.10.10

本篇为楼主自己的React学习笔记,所有描述都是楼主自己的理解,不一定是正确的描述,请酌情理解,如能指出错误会相当感谢。

首先是React的包,适用于单页面应用时直接导入

 <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
//开发
<script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>
//生产

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
//JSX编译器

有单页面也就有直接拉项目结构的,这和Vue一样

npx create-react-app my-app
cd my-app
npm start

1.JSX

这是一个JavaScript的语法扩展,能很好的适配React,在代码上提升视觉辅助作用,还能让React显示更多有用的错误和警告信息。

在jsx中嵌入表达式

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);

同时jsx也是一个表达式,可以return一个JavaScript对象

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

2.元素渲染

渲染一个React元素,将其传入ReactDOM.render().

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

React元素是不可变对象,所以更新UI,其实为创建一个新的元素,再将其传入一次ReactDOM.render().

一个计时器案例

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

React会自动检测查重然后只更新需要更新的部分,即传入一个UI树,只会更新实际改变了的内容,这样能消除一整类的BUG(Vue是不是也是这样的呢?忘了)

3.组件和Props

函数组件

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

class 组件(ES6)

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

以上两组件React中等效

渲染组件

const element = <Welcome name="Sara" />;

以及如何去渲染到页面上

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

注意:自定义组件名称必须以大写字母开头,小写会被视为原生DOM。

组合组件

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

渲染组件的嵌套

提取组件

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}//Comment父组件

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}//Comment中提取出来的UserInfo组件

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}//以及进一步的Avatar组件

这样组件的嵌套,提高复用性,更容易维护,也更适合大型应用。

props的只读属性

组件不能修改自身的props,相当于不会修改入参的纯函数一般

而如下则不是一个纯函数

function withdraw(account, amount) {
  account.total -= amount;
}

React规定所有组件都必须像纯函数一样保护它们的props不被修改。

4.State & 生命周期

因为props是只读的,为了给组件提供一个可修改的属性,所以有了state.

以下是一个计时器的案例

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

使用state要注意的事:

1.不要直接修改state,而是使用setState(),只有构造函数是state唯一能赋值的地方。

2.state的更新可能是异步的

因为?this.props?和?this.state?可能会异步更新,所以不要依赖他们的值来更新下一个状态。

this.setState({
  counter: this.state.counter + this.props.increment,
});// Wrong

以上代码可能会无法更新计数器,需要把操作写进函数

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));// Correct

3.state的更新会被合并

意思是state包含多个独立的变量,你可以单独修改其中每一个变量,不会影响其他变量的值。

4.数据向下流动

意思是父组件的state可以传给子组件的props,因为state是局部封装的,子组件的props的只读不会收到影响。同时引用相同组件的三个兄弟对象的值也都是各自自己的,不会相互影响。

生命周期

1.组件初始化(initialization)

也就是constructor构造方法,需要继承React.Component这个类,才有了render()类,生命周期方法才能用。

super(props)用来调用基类Component的构造方法,把props注入给子组件,而state则是手动设置的,这也是为什么props只读,state可以修改。

2.组件的挂载(Mounting)

此阶段分为componentWillMount,render,componentDidMount三个时期。

componentWillMount:在组件挂载到DOM之前调用,只会被调用一次,此类中写this,setState不会调用,而且这里的内容也能写进constructor,所以很少用。

render:根据props和state,return一个React元素,不负责渲染工作,是纯函数。

componentDidMount:组件挂载到DOM后调用,只会调用一次。

3.更新(update)

React更新机制:setState引起的state更新或者父组件的render引起的props更新,都会重新render.

此阶段分为componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate

componentWillReceiveProps(nextProps):在props引起的组件更新中调用,可以用来判断props值有没有改变,如果没有改变可以不执行重新渲染操作。

?shouldComponentUpdate:因为父组件重新render会让所有子组件都重新渲染,所以给Child组件加上shouldComponentUpdate()函数来优化这个情况。如此父组件更新后子组件如果没有变化就不会重新渲染。该方法同样也适用子组件自己setState()后是相同值的情况。

class Child extends Component {
   shouldComponentUpdate(nextProps){ 
        if(nextProps.someThings === this.props.someThings){
          return false
        }
    }
    render() {
        return <div>{this.props.someThings}</div>
    }
}//优化后子组件没有改变便不会重新渲染

componentWillUpdate:调用render前执行,少用。

render:同上文

componentDidUpdate:在组件更新后调用,可以操作组件更新.

4.卸载阶段

此阶段只有componentWillUnmount

componentWillUnmount:在组件被卸载前调用,可以在这里清理定时器,componentDidMount中手动创建的DOM等,避免内存泄漏。

React v16.4+ 的生命周期

变更原因:

原React生命周期在Fiber的到来下,如下生命周期函数的调用不再是必定只调用一次了。

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

以上生命周期函数被归类到Fiber新的更新阶段中的Reconciliation Phase(和解阶段)。在这个阶段中每走一个时间片会重新检测有没有紧急任务,如果有就会放弃当前执行的函数去完成紧急任务,之后再重新走之前没执行完的生命周期方法。

重点是这个是重新执行方法,而不是从断开部分执行,所以如果其中有ajax请求的话就会多次发起,显然这是不对的。

新的生命周期:getDerivedStateFromProps,getSnapshotBeforeUpdate

getDerivedStateFromProps:取代了之前的componentWillMount,componentWillReceiveProps,componentWillUpdate。作为一个静态函数,只能做无副作用的操作,局限在根据props和state决定新的state操作之中。React v16.4+版本后在组件挂载和更新之前都必定被调用。应返回一个对象来更新状态,或者是返回Null不更新任何内容。该方法要在声明是加上static。

getSnapshotBeforeUpdate:被调用于render之后,它可以在你能读取不能使用DOM的时候在可能更改之前从DOM中捕获一些信息,可以用来记录滚动位置等。此生命周期返回的值都会作为参数传给componentDidUpdate()。

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    //我们是否要添加新的 items 到列表?
    // 捕捉滚动位置,以便我们可以稍后调整滚动.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    //如果我们有snapshot值, 我们已经添加了 新的items.
    // 调整滚动以至于这些新的items 不会将旧items推出视图。
    // (这边的snapshot是 getSnapshotBeforeUpdate方法的返回值)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:25:59  更:2021-10-11 17:26:26 
 
开发: 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年5日历 -2024/5/18 19:53:23-

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