react 常用api

一.react元素创建使用

import ReactDOM from 'react-dom/client';
// 创建一个react元素
const App=
我是react-app
// 获取根元素 const root = ReactDOM.createRoot(document.getElementById('root')); // 渲染元素 root.render(App);

二.组件

函数式组件

function componentFun(props){
	const {name,age} = props;
	const onClick=()=>{
		console.log('点击事件')
	}
	return 
我是函数式组件{name}-{age}
}

类组件

    *   类组件的props是存储到类的实例对象中,
    *       可以直接通过实例对象访问
    *       this.props
    *   类组件中state统一存储到了实例对象的state属性中
    *       可以通过 this.state来访问
    *       通过this.setState()对其进行修改
    *           当我们通过this.setState()修改state时,
    *               React只会修改设置了的属性

	import React, {Component} from 'react';
	Class App extentds React.Component {
		// 声明ref 绑定dom 用于直接操作dom
		divRef = React.createRef();
		state = {
			count: 0,
			test: '水电费啦',
		}
		// 为了省事,在类组件中响应函数都应该以箭头函数的形式定义
		onClick = ()=>{
			 this.setState(prevState => {
	             return {
	                 count: prevState + 1
	             }
	         });
	         /*this.setState({
	            obj:{...this.state.obj, name:'沙和尚'}
	        });*/
			console.log("点我啊",this.divRef)
		}
		redner(){
			return 
我是一个类组件{this.props.name}-{this.props.age} {this.state.count}-{this.state.test}
我是divRef
} }

三.useState 实现数据双向绑定

import React,{useState} from 'react'
const [formData,setFormData]=useState({
	inputDesc:''
})
const onInputChange=(e)=>{
	setFormData({
         ...formData,
         inputTime: e.target.value
     });
}
return 

四.createPortal 将传入的虚拟节点,插入到指定dom节点中

import ReactDOM from 'react-dom'
// 获取backdrop的根元素
const backdropRoot = document.getElementById('backdrop-root');
const Backdrop = (props) => {
	// props.children  为插入的子节点 类似于vue的插槽
    return ReactDOM.createPortal(
{props.children}
, backdropRoot); };

五.React.Fragment 是一个专门用来作为父容器的组件

const App = () => {

    /*
    *           它只会将它里边的子元素直接返回,不会创建任何多余的元素
    *       - 当我们希望有一个父容器
    *           但同时又不希望父容器在网页中产生多余的结构时
    *           就可以使用Fragment
    * */

    return (
        <>
           
第一个组件
第二个组件
第三个组件
); };

六.createContext

  1. 在store文件下,创建一个testContext.js文件
import React from 'react';
/*
*   Context相当于一个公共的存储空间,
*       我们可以将多个组件中都需要访问的数据统一存储到一个Context中,
*       这样无需通过props逐层传递,即可使组件访问到这些数据
*
*   通过React.createContext()创建context
*
* */

const TestContext = React.createContext({
    name:'孙悟空',
    age:18
});

export default TestContext;
  1. 父组件的引入暴露
import TextContext from "./store/testContext"
const APP=()=>{
	const [] = useState({
		items: [],
	    totalAmount: 0,
	    totalPrice: 0,
	})
	return (
		
	)
}

  1. 子组件B中使用
import React, {useContext} from 'react';
import TestContext from "../store/testContext";
*   当我们通过Context访问数据时,他会读取离他最近的Provider中的数据,
*       如果没有Provider,则读取Context中的默认数据
const B = () => {
    // 使用钩子函数获取Context
    const ctx = useContext(TestContext);
    return (
        
{ctx.name} -- {ctx.age}
); }; export default B;

4.子组件A中使用

import React from "react";
import TestContext from "../store/testContext";
 *       使用 Xxx.Consumer 组件来创建元素
 *       Consumer 的标签体需要一个回调函数
 *       它会将context设置为回调函数的参数,通过参数就可以访问到context中存储的数据
const A = () => {
  return (
    
      {(ctx) => {
        return (
          
{ctx.name} - {ctx.age}
); }}
); }; export default A;

七.useEffect

const App = () => {
  const [count, setCount] = useState(0);
  
  // setCount(0);
  /*
   * Too many re-renders.
   *   - 当我们直接在函数体中调用setState时,就会触发上述错误
   *   - 问题:
   *             当新的state值和旧值相同时,它是不会触发组件的重新渲染的
   *   - setState()的执行流程(函数组件)
   *       setCount() --> dispatchSetDate()
   *            -->会先判断,组件当前处于什么阶段
   *                 如果是渲染阶段 --> 不会检查state值是否相同
   *                 如果不是渲染阶段 --> 会检查state的值是否相同
   *                     - 如果值不相同,则对组件进行重新渲染
   *                     - 如果值相同,则不对组件进行重新渲染
   *                       如果值相同,React在一些情况下会继续执行当前组件的渲染
   *                          但是这个渲染不会触发其子组件的渲染,这次渲染不会产生实际的效果
   *                          这种情况通常发生在值第一次相同时
   *
   * */
  
  //  useEffect()是一个钩子函数,需要一个函数作为参数,
  //  这个作为参数的函数,将会在组件渲染完毕后执行
  //  在开发中,可以将那些会产生副作用的代码编写到useEffect的回调函数中
  //  这样就可以避免这些代码影响到组件的渲染
  useEffect(() => {
    setCount(1);
  });

  const clickHandler = () => {
    console.log("点击按钮!");
    setCount(1);
  };

  return (
    
{count}
); }; /* * 默认情况下,useEffect()中的函数,会在组件渲染完成后调用, * 并且是每次渲染完成后都会调用 * * 在useEffect()可以传递一个第二个参数, * 第二个参数是一个数组,在数组中可以指定Effect的依赖项 * 指定后,只有当依赖发生变化时,Effect才会被触发 * 通常会将Effect中使用的所有的局部变量都设置为依赖项 * 这样一来可以确保这些值发生变化时,会触发Effect的执行 * 像setState()是由钩子函数useState()生成的 * useState()会确保组件的每次渲染都会获取到相同setState()对象 * 所以setState()方法可以不设置到依赖中 * 如果依赖项设置了一个空数组,则意味Effect只会在组件初始化时触发一次 * */ useEffect(()=>{ setCount(1); },[count]);

八.useReducer

// 引入
import React, { useReducer } from 'react';

// 定义cartReducer  一定要return
const cartReducer = (state, action)=>{
    switch (action.type){
        case 'ADD':
                return {...state,count:state.count+action.count};
        default:
            return state;
    }
};

 const [cartData, cartDispatch] = useReducer(cartReducer, {
        count:0
});

// 使用
cartDispatch({type:'ADD', count:5});

九.React.memo 允许你的组件在 props 没有改变的情况下跳过重新渲染。

import React from 'react';
const B = (props) => {
    return (
        
{props.test}--组件B
); }; /* * React.memo() 是一个高阶组件 * 它接收另一个组件作为参数,并且会返回一个包装过的新组件 * 包装过的新组件就会具有缓存功能, * 包装过后,只有组件的props发生变化化 * 才会触发组件的重新的渲染,否则总是返回缓存中结果 * */ export default React.memo(B);

十.useCallback

const App = () => {
    const [count, setCount] = useState(1);
    const [num, setNum] = useState(1);
    /*
    *   useCallback()
    *       参数:
    *           1. 回调函数
    *           2. 依赖数组
    *               - 当依赖数组中的变量发生变化时,回调函数才会重新创建
    *               - 如果不指定依赖数组,回调函数每次都会重新创建
    *               - 一定要将回调函数中使用到的所有变量都设置到依赖数组中
    *                   除了(setState)
    * */
    const clickHandler = useCallback(() => {
        setCount(prevState => prevState + num);
        setNum(prevState => num + 1);
    }, [num]);

    return (
        
    );
};

十一.redux的使用

1.使用createSlice 创建reducer的切片(新建一个store/index.js文件)

//使用RTK来构建store
import {configureStore, createSlice} from "@reduxjs/toolkit";

// createSlice 创建reducer的切片
// 它需要一个配置对象作为参数,通过对象的不同的属性来指定它的配置
const stuSlice = createSlice({
    name:'stu', // 用来自动生成action中的type
    initialState:{
        name:'孙悟空',
        age:18,
        gender:'男',
        address:'花果山'
    }, // state的初始值
    reducers:{ // 指定state的各种操作,直接在对象中添加方法
        setName(state, action){
            // 可以通过不同的方法来指定对state的不同操作
            // 两个参数:state 这个state的是一个代理对象,可以直接修改
            state.name = '猪八戒';
        },
        setAge(state, action){
            state.age = 28;
        }
    }
});

// 切片对象会自动的帮助我们生成action
// actions中存储的是slice自动生成action创建器(函数),调用函数后会自动创建action对象
// action对象的结构 {type:name/函数名, payload:函数的参数}
export const {setName, setAge} = stuSlice.actions;

// const nameAction = setName('哈哈');
// const ageAction = setAge(30);
// console.log(nameAction);
// console.log(ageAction);

// 创建store 用来创建store对象,需要一个配置对象作为参数
const store = configureStore({
   reducer:{
       student:stuSlice.reducer
   }
});

export default store;

2.在需要使用store顶级组件中暴露store

import ReactDOM from "react-dom/client";
import App from "./App";
import {Provider} from "react-redux";
import store from './store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    
        
    
);

3.引入使用

import React from 'react';
import {useDispatch, useSelector} from "react-redux";
import {setName, setAge} from './store';

const App = () => {
    // useSelector() 用来加载state中的数据
    const student = useSelector(state => state.student);
    // 通过useDispatch()来获取派发器对象
    const dispatch = useDispatch();
    // 获取action的构建器

    const setNameHandler = () => {
        dispatch(setName('沙和尚'));
    };

    const setAgeHandler = () => {
        dispatch(setAge(33));
    };

    return (
        

{student.name} --- {student.age} --- {student.gender} --- {student.address}

); }; export default App;

你可能感兴趣的:(react.js,javascript,前端)