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 (
           
{ this.props.children}
) } ReactDOM.renderr(
Dome this.props.children的内容
, document.getElementById('root'))

父子传参

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

条件渲染

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

const Greeting = props => {
  const isLoggedIn = props.isLoggedIn
  if (isLoggedIn) {
    return 
  }
  return 
}



render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    
The user is {isLoggedIn ? 'currently' : 'not'} logged in.
); }
阻止组件渲染 在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。让 render 方法返回 null 而不是它的渲染结果即可实现

列表 & Keys

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

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

  const list = messages.map(t => 
  • {t}
  • ) return
      {list}
    }

    表单

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

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

    1、受控组件


    Email:

    ) }

    ref

    用来访问dom对象

     
    取: 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 (
        <>
          

    {count}

    ) } 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 (
            

    我是A组件的名字{name}我是A的子组件{name}

    ) } const B =() => { const { name } = useContext(AppContext) return (

    我是B组件的名字{name}

    ) } return ( ) } 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 (
    <>
    

    {state.count}

    ) } export default AddCount

    useEffect():副作用钩子

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

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

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

    你可能感兴趣的:(react 基础知识)