React Hooks

JSX语法:

JSX将HTML语法直接加入到JS代码中,在通过翻译器转换到纯js后由浏览器执行,实际开发中,JSX在产品打包阶段已经编译为js,无副作用,让代码易于维护更加直观,编译过程由Babel的JSX编译器实现。

类组件开发

import React from 'react'
import Child from './components/Child'
 
export default class Demo extends React.Component{
    state={
        info:{} //传递给子组件
    }
 
    saveList(list){
        //子组件传来的数据
        console.log(list)
    }
    render(){
        
} }

函数式组件开发

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    
logo

Edit src/App.js and save to reload.

Learn React
); } export default App;

hooks(react 16.8版本以后才支持)

高阶组件为了复用,导致代码层级复杂,生命周期复杂,写成function组件,无状态组件,写成class类组件,成本过高,我们可以使用react hooks

useState(保存组件状态)

const [state,setState] = useState(inintialState)

示例: 

import { useState } from 'react';

function App() {
  const [name, setName] = useState('张三')
  const [text, setText] = useState('')
  const [list, setList] = useState([])
  const [age, setAge] = useState(88)

  function addList() {
    setList([...list, text])
    setText('')
  }
  function handleChange(e) {
    setText(e.target.value)
  }
  function handleDelete(index) {
    console.log(index);
    let arr = [...list]
    arr.splice(index, 1)
    console.log(arr);
    setList(arr)
  }
  return (
    
app-{name} app-{age}
handleChange(e)} value={text} />
    { list.map((el, index) => { return
  • {el}
  • }) }
{!list.length &&
暂无事项
}
); } export default App;

useEffect(处理副作用)和useLayoutEffect(同步执行副作用)

第二个参数为空数组时,此函数只执行一次,相当于 componentDidMount 生命周期函数

import { useState,useEffect } from 'react';

function App() {
  const [list, setList] = useState([])
  useEffect(()=>{
    setList([11])
  },[])
  return (
    
    { list.map((el, index) => { return
  • {el}
  • }) }
); } export default App;

第二个参数传入参数时,此函数会监听该参数的变化,且再次执行该函数,相当于 componentDidUpdate 生命周期函数

import { useState,useEffect } from 'react';

function App(props) {
  const [name, setName] = useState("apple")
  useEffect(()=>{
    setName(name.toUpperCase())
  },[name])
  return (
    
app-{name}
); } export default App;

useEffect和useLayoutEffect用法基本一致,唯一不同点就是调用时机不同,useLayoutEffect和原来 componentDidMount componentDidUpdate一致,react完成dom后马上同步调用的代码,会阻塞页面渲染,useEffect会再页面渲染完成后才调用。

useCallback(记忆函数)

防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数发生变化了,才重新声明一次。(因为每次调用useState中的set函数就会触发组件渲染)

在函数内用到的所有变量,需要写在第二个参数数组中,可以监听到变化渲染师重新生成新的函数,如果不写,那么永远都是不会重新生成新的函数,并且使用到的变量值都是旧的,不会更新。

import { useState, useEffect, useCallback } from 'react';

function App() {
  let [name, setname] = useState(0)
  const handleChange = useCallback(() => {
    setname(name + 1);
  }, [name])
  return (
    
app-{name}
); } export default App;

useMemo记忆组件

useCallback的功能完全可以由useMemo所取代,如果你想通过使用useMemo返回一个记忆函数也是完全可以的。

useCallback(fn,inputs)
useMemo(()=>fn,inputs)

唯一区别是:useCallback不会执行第一个参数函数,而是将它返回给你,而useMemo会执行第一个函数并且将函数执行结果返回给你。

所以useCallback常用于记忆事件函数,生成级以后得事件传给子组件使用;而useMemo更适合经过函数计算得到一个确定的值,比如记忆组件。类似于vue中的computed计算属性

import { useState, useEffect, useCallback, useMemo } from 'react';

function App() {
  let [name, setname] = useState(0)
  const name2 = useMemo(() => name+1000, [name])
  const handleChange = useCallback(() => {
    setname(name + 1);
  }, [name])
  return (
    
app-{name}

{name2}

); } export default App;

useRef(保存引用值)

1.能够用来定位元素或者组件

2.能够存储变量

import { useRef, useState } from 'react';

function App() {
  let [count,setCount] = useState(0)
  const myName = useRef()
  const myCount = useRef(0)
  return (
    
app

{myCount.current}

); } export default App;

useContext(减少组件层级)

import React,{useContext, useState, createContext} from 'react';

const CountContext = createContext();//创建Context对象
const TestContext = () =>{
    const [count, setCount] = useState(0);
    console.log(CountContext);
    console.log(useContext(CountContext));
    return(
      

父组件点击次数:{count}

) }; const Counter = () => { const count = useContext(CountContext); console.log(CountContext); // console.log(count); // console.log(useContext(CountContext)); return (

子组件获得的点击数量:{count}

); }; export default TestContext;

useReducer

redux的钩子函数,状态数据管理,可以在APP.js中定义一次,在其他组件中传入state, dispatch,进行调用

import { useReducer } from 'react';
//处理函数
const reducer = (preState, action) => {
  let newState = {...preState}

  switch (action.type) {
    case 'add':
      newState.count++
      return newState
    case 'minus':
      newState.count--
      return newState
    default:
      return preState
  }
}

const initialState = {
  count: 0
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState)

  return (
    
{state.count}
); } export default App;

可搭配useContext使用

import { useReducer, createContext, useContext } from 'react';
//处理函数
const reducer = (preState, action) => {
  let newState = { ...preState }

  switch (action.type) {
    case 'add':
      newState.count++
      return newState
    case 'minus':
      newState.count--
      return newState
    default:
      return preState
  }
}

const initialState = {
  count: 0
}
const CountContext = createContext()

function App() {
  const [state, dispatch] = useReducer(reducer, initialState)
  return (
    
      
); } function Child1() { const obj = useContext(CountContext) return
child1-{obj.state.count}
} function Child2() { const obj = useContext(CountContext) return
child1-{obj.state.count}
} export default App;

  useId

useId 是一个 React Hook,可以生成传递给无障碍属性的唯一 ID。

const id = useId()

 自定义hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中

必须以 use 开头,如不遵循,由于无法判断某个函数是否包含对其内部hook的调用,React将无法自动检查你的hook是否违反了hook规则,与vue3中自定义组合式api用法相同。

import { useState,useEffect } from 'react';

function useList(){
  const [list, setList] = useState([])
  useEffect(()=>{
    setList([11])
  },[])
  return{
    list
  }
}
function App() {
  const {list} = useList()
  return (
    
    { list.map((el, index) => { return
  • {el}
  • }) }
); } export default App;

参考文档:内置 React Hook – React 

你可能感兴趣的:(我的笔记,前端,hooks,react)