react 基础知识

生命周期 旧

初始化阶段

由React.render 触发 -- 初次渲染
  1. constructor() 构造函数
  2. componentWillMount() 组件挂前
  3. render() 渲染
  4. componentDidMount() 组件挂载后

更新阶段

由组件内部this.setState() 或 父组件render触发
  1. componentWillReceiveProps(nextProps) 当props发生变化时
  2. shouldComponentUpdate(nextProps,nextState) 是否更新, return true 更新 false不更新
  3. componentWillUpdate (nextProps,nextState) 组件更新前
  4. render() 渲染
  5. componentDidUpdate(prevProps,prevState) 组件内更新完毕

卸载组件

由ReactDOM.unmountComponentAtNode(要卸载的元素节点) 触发
  1. componentWillUnmount() 卸载组件


    生命周期 - 旧

生命周期 新

初始化阶段:

由ReactDOM.render()触发-----初次渲染
  1. constructor()
  2. getDerivedStateFromProps-------表明state完全取决于props
  3. render()
  4. componentDidMount()

更新阶段:

由组件内部this.setSate()或父组件重新render触发
  1. getDerivedStateFromProps
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate-------在更新之前保留页面的快照信息
  5. componentDidUpdate()

卸载组件:

由ReactDOM.unmountComponentAtNode()触发
  1. componentWillUnmount()

新旧区别:

首先是给三个生命周期函数加上了 UNSAFE:
1. UNSAFE_componentWillMount
2. UNSAFE_componentWillReceiveProps
3. UNSAFE_componentWillUpdate

原来(React v16.0前)的生命周期在React v16推出Fiber之后就不合适了,因为如果要开启async rendering,在render函数之前的所有函数,都有可能被执行多次。
禁止不能用比劝导开发者不要这样用的效果更好,所以除了shouldComponentUpdate,其他在render函数之前的所有函数(componentWillMount,componentWillReceiveProps,componentWillUpdate)都被getDerivedStateFromProps替代。
如果在v16.3后的版本使用三个被禁用的生命周期,在其前面需要加上UNSAFE__,而在v17版本有可能直接被干掉无法使用。

同时新增了两个生命周期函数:

  1. getDerivedStateFromProps
  2. getSnapshotBeforeUpdate
static getDerivedStateFromProps(props, state) 静态方法生命周期钩子

getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
我们知道getDerivedStateFromProps是一个静态函数,在其中是无法访问到组件实例的,也就是强制开发者在render之前只做无副作用的操作,而是根据props和state决定新的state,仅此而已。

getSnapshotBeforeUpdate(prevProps, prevState) 保存状态快照

getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate(prevProps, prevState, snapshot)。

生命周期 - 新

基础知识

JSX语法

JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 {开头),就用 JavaScript 规则解析

JSX 语法允许直接在模板插入 JavaScript 变量,如果这个变量是一个数组,则会展开这个数组的所有成员(数组成员可以为 HTML 元素)

React 组件

React 允许将代码封装成组件,然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass() 方法就用于生成一个组件类。

所有组件都必须有自己的 render 方法,用于输出组件。组件类的第一个字母必须大写。

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性(组件属性用 this.props 对象获取)

组件属性 class 需要用 className 代替,for 用 htmlFor 代替,因为 class 和 for 为 JavaScript 保留字。

this.props.children

this.props 对象的属性与组件的属性一一对应,但是有一个例外,this.props.children 表示组件所有子节点。

相当于vue的 slot

       function Dome() {
         return (
           <div>
               { this.props.children} 
            </div>
         )
       }
       
       ReactDOM.renderr(<Dome> <div>Dome  this.props.children的内容</div> </Dome>, document.getElementById('root'))

父子传参

父传子通过props传的, this.props.xxx接收
子传父 通过props传递方法 子调用该方法通过实参传递

条件渲染

React 中的条件渲染和 JavaScript 中的一致,使用 JavaScript 操作符 或 [条件运算符] && || (来创建表示当前状态的元素,然后让 React 根据它们来更新 UI

const Greeting = props => {
  const isLoggedIn = props.isLoggedIn
  if (isLoggedIn) {
    return <UserGreeting />
  }
  return <GuestGreeting />
}



render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}


阻止组件渲染 在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。让 render 方法返回 null 而不是它的渲染结果即可实现

列表 & Keys

const messages = ['hello', 'hi', 'how are you']

const List = props => {
  const { messages } = props

  const list = messages.map(t => <li key={t}>{t}</li>)
  return <ul>{list}</ul>
}

表单

当用户提交表单时,HTML 的默认行为会使这个表单跳转到一个新页面。在 React 中亦是如此。

但大多数情况下,我们都会构造一个处理提交表单并可访问用户输入表单数据的函数。实现这一点的标准方法是使用一种称为受控组件的技术。

1、受控组件

<input> 或 <select> 都要绑定一个 change 事件,每当表单的状态发生变化,都会被写入组件的 state 中,这种组件在 React 中被称为受控组件。

2. 处理多个输入

你有处理多个受控的 input 元素时,你可以通过给每个元素添加一个 name 属性,来让处理函数根据 event.target.name 的值来选择做什么。

 handleChange = event => {
    const { value, name } = event.target

    this.setState({
      [name]: value
    })
  }

  handleSubmit = e => {
    console.log(`${this.state.username} ${this.state.email}`)
    e.preventDefault()
  }

  render() {
    return (
      <div>
        Username:
        <input
          name="username"
          type="text"
          value={this.state.username}
          onChange={this.handleChange}
        />
        <br />
        Email:
        <input
          name="email"
          type="text"
          value={this.state.email}
          onChange={this.handleChange}
        />
        <br />
        <button onClick={this.handleSubmit}>提交</button>
      </div>
    )
  }


ref

用来访问dom对象

 <input ref="input" />
取: this.refs.input

React Hooks

React的组件创建方式,一种是类组件,一种是纯函数组件

特点: 1. 纯函数组件没有状态
2. 纯函数组件没有生命周期
3. 纯函数组件没有this
4. 只能是纯函数
React Hooks 的意思是,组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来。而React Hooks 就是我们所说的“钩子”。

React Hooks的用法
一、userState():状态钩子

纯函数组件没有状态,useState()用于为函数组件引入状态。
下面我们使用Hooks重写上面的计数器

import React, {useState} from 'react'
const AddCount = () => {
  const [ count, setCount ] = useState(0)
  const addcount = () => {
    let newCount = count
    setCount(newCount+=1)
  } 
  return (
    <>
      <p>{count}</p>
      <button onClick={addcount}>count++</button>
    </>
  )
}
export default AddCount 

useState这个函数接收的参数是我们的状态初始值(initial state),它返回了一个数组,这个数组的第[0]项是当前当前的状态值,第[1]项是可以改变状态值的方法函数,我们约定为set前缀加状态的变量名

二、useContext():共享状态钩子

该钩子的作用是,在组件之间共享状态。关于Context这里不再赘述,其作用就是可以做状态的分发,在React16.X以后支持,避免了react逐层通过Props传递数据。
下面是一个例子,现在假设有A组件和B组件需要共享一个状态

import React,{ useContext } from 'react'
const Ceshi = () => {
  const AppContext = React.createContext({})
  const A =() => {
    const { name } = useContext(AppContext)
    return (
        <p>我是A组件的名字{name}<span>我是A的子组件{name}</span></p>
    )
}
const B =() => {
  const { name } = useContext(AppContext)
  return (
      <p>我是B组件的名字{name}</p>
  )
}
  return (
    <AppContext.Provider value={{name: 'hook测试'}}>
    <A/>
    <B/>
    </AppContext.Provider>
  )
}
export default Ceshi 

三、useReducer():Action钩子

如遇到状态管理,我们一般会用到Redux,而React本身是不提供状态管理的。而useReducer()为我们提供了状态管理。

import React,{useReducer} from 'react'

const AddCount = () => {
const reducer = (state, action) =>  {
 if(action.type === ''add){
  return {
  ...state,
  count: state.count +1,
  }
 }else {
   return state
  }
 }
const addcount = () => { 
  dispatch({
    type: 'add'
  })
 }
const [state, dispatch] = useReducer(reducer, {count: 0})
return (
<>
<p>{state.count}</p>
<button onClick={addcount}>count++</button>
</>
)
}
export default AddCount

useEffect():副作用钩子

组件中没有生命周期,那么可以使用 useEffect 来替代。如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合
默认情况下,它在第一次渲染之后和每次更新之后都会执行。你可能会更容易接受 effect 发生在“渲染之后”这种概念,不用再去考虑“挂载”还是“更新”。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。

useEffect(() => {
   // 你需要执行的代码
}, []); 

useEffect 初始化被调用一次,数据更新会被调用, 传空数组表示只初始化调用一次, 当传[num, count] 表示:
当num或count值被改变,回调就会被调用, (数组里放的表示你要监听的值)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容