hook(useState、useEffect、useReducer)、context、React项目起始

React知识点收尾及项目开始

hook

官网:React – A JavaScript library for building user interfaces

Hook 简介 – Reacticon-default.png?t=LA92https://zh-hans.reactjs.org/docs/hooks-intro.html

react拥有两种组件,类组件和函数组件,其中函数组件默认没有生命周期和状态数据,hook填补了这个空缺。

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

useState

没有状态数据的前提下,函数组件当中的数据修改后很难刷新

export default function layout(){
    var msg = 0
    const addMsg=()=>{
        msg++
        console.log(msg)
    }
    return <>
        <p>{msg}</p>
        <button onClick={addMsg}>加</button>
    </>
}

使用useState

1、定义useState方法,然后传入初始值

2、useState会返回两个参数,分别是state数据和可以刷新设置数据的方法

import React, { useState } from 'react';
export default function Layout(){
    const [count, setCount] = useState(0);
    const addMsg=()=>{
        setCount(count + 1)
    }
    return <>
        <p>{count}</p>
        <button onClick={addMsg}>加</button>
    </>
}

如果state是多个数据,必须都发生修改,否则,没有修改的数据被置空覆盖了

import React, { useState } from 'react';
import img from "../asserts/image/1.jpg"
export default function Layout(){
    const [count, setCount] = useState({isShow:1,title: "隐藏"});
    const toggle = ()=>{
        if(count.isShow){
            setCount({title: "显示"})
        }else{
            setCount({isShow:1,title: "隐藏"})
        }
        console.log(count)
    }
    return <>
        <p>
            {
                count.isShow===1?<img src={img} style={
   
   {width:"100px"}} />:""
            }
        </p>
        <button onClick={toggle}>{count.title}</button>
    </>
}

useEffect

作用: 可以让函数组件拥有自己的生命周期

useEffect会在组件第一次挂载完毕, 更新完毕, 组件即将卸载的时候自动触发,相当于类组件中componentDidMount , componentDidUpdate, componentWillUnmount三个钩子函数的集合

  • componentDidMount :组件初始化挂载之后,执行useEffict当中的语句,不执行useEffict当中返回的函数

  • componentDidUpdate :组件初始化挂载之后,先执行useEffict当中返回的函数,再执行useEffict当中的语句

  • componentWillUnmount:只执行useEffict当中返回的函数

import React, { useEffect,useState } from 'react';
export default function Home(){
    let [state,setState] = useState("我是home组件")
    useEffect(
        ()=>{
            var obj = document.querySelector("#home_id")
            console.log("我执行了",obj)
            return ()=>{
                console.log("我是home组件的嵌套函数,我执行了",obj)
            }//这个函数在组件卸载前执行
        }
    )
    const change = ()=>{
        setState("hello,我确实是home组件")
    }
    return <>
      <p id="home_id" onClick={change}>{state}</p>
    </>
}

useEffect在所有组件内数据发送修改都执行,这个不合适。

useEffect拥有两个参数

  • 第一个参数是一个操作函数,包含两部分,执行的语句,和返回的函数

  • 第二个参数是一个数组,数组的元素是要监听的变量

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

export default function Home(){
    let [state,setState] = useState("我是home组件")
    let [hhh,setHhh] = useState("hhhh")
    
    useEffect(
        ()=>{
            var obj = document.querySelector("#home_id")
            console.log("我执行了",obj)
            return ()=>{
                console.log("我是home组件的嵌套函数,我执行了",obj)
            }
        },[state]
    )
    const change = ()=>{
        setState("hello,我确实是home组件")
    }
    const changeHhh = ()=>{
        setHhh("哈哈哈")
    }
    return <>
      <p id="home_id" onClick={change}>{state}</p>
      <p id="home_id" onClick={changeHhh}>{hhh}</p>
    </>
}

useEffict返回的函数通常用来回收内容。

import React, { useEffect,useState } from 'react';
var timer = ""
export default function Home(){
    let [now,setTime] = useState(Date.now())
    useEffect(
        ()=>{
            return ()=>{
                clearInterval(timer)
                console.log("我是home组件的嵌套函数,我执行了")
            }
        },[]
    )
    const start= ()=>{
        timer = setInterval(()=>{
            setTime(Date.now())
        },1)
    } 
    const end=()=>{
        clearInterval(timer)
    }   
    return <>
        <p>{now}</p>
        <button onClick={start}>开始</button>
        <button onClick={end}>停止</button>
        
    </>
}

useReducer

作用: 可以让函数组件拥有自己的状态数据

  • 参数1: 数据处理 函数reducer

  • 参数2: 数据默认值

  • 返回值: 数组

    • 第一个元素: 状态数据对象

    • 第二个元素: dispatch数据更新方法, dispatch可以发送一个数据操作对象action给数据处理函数reducer

代码如下:

import React, { useReducer } from 'react';
export default function Home() {
    const reducer = (state, action) => {
        var data = action.data
        switch (action.type) {
            case 'add':
                var obj = state + data
                return obj
            case 'cut':
                var objs = state - data
                return objs
            default:
                return state
        }
    }
    const [state, dispatch] = useReducer(reducer, 0)
    const change_add = () => {
        dispatch({type: 'add',data: 10})
    }
    const change_cut = () => {
        dispatch({type: 'cut',data: 5})
    }
    return <>
        <div style={
   
   { width: "200px", margin: "0 auto" }}>
            <button onClick={change_add}>增加</button>
            <p>{state}</p>
            <button onClick={change_cut}>减少</button>
        </div>
    </>
}

context

在复杂的嵌套情况下,组件之间传参不能很方便,所以需要有一个之间可以传参的方法,就是context

生成消费者模式

consumer(消费者)

第一种写法:

1、导入myContext

2、使用<myContext.Consumer>标签

3、标签内部需要由一个函数接受myContext的数据

4、使用数据

import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
    state={
        msg: "先辈参数 abc"
    }
    render() {
        return (
            <div className="grandpa">
                我是先辈组件 --- 先辈参数 - {this.state.msg}
                <br/>
                <myContext.Consumer>
                    {
                        (context)=>{
                            console.log(context)
                            return <>
                                {
                                    context.list.map(item=>(
                                        <p key={item.id}>{item.name}</p>
                                    ))
                                }
                            </>
                        }
                    }
                </myContext.Consumer>
                <br/>
                <Father msg={this.state.msg}></Father>
            </div>
        )
    }
}

第二种写法:

import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
    state={
        msg: "先辈参数 abc"
    }
    static contextType = myContext //contextType固定写法
    render() {
        console.log(this.context)
        return (
            <div className="grandpa">
                我是先辈组件 --- 先辈参数 - {this.state.msg}
                <br/>
                    {
                        this.context.list.map(item=>(
                            <p key={item.id}>{item.name}</p>
                        ))
                    }
                <br/>
                <Father msg={this.state.msg}></Father>
            </div>
        )
    }
}

provider(生产者)

采用<myContext.Provider value={this.state.gList}>传递参数context

import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
    state = {
        msg: "先辈参数 abc",
        gList: [
            {
                id: 4,
                name: "净坛使者"
            },
            {
                id: 3,
                name: "浴皇大帝"
            },
            {
                id: 2,
                name: "揍死"
            },
            {
                id: 1,
                name: "如来"
            },
        ]
    }
    render() {
        console.log(this.context)
        return (
            <div className="grandpa">
                我是先辈组件 --- 先辈参数 - {this.state.msg}
                <br/>
                <myContext.Provider value={this.state.gList}>
                    <myContext.Consumer>
                        {
                            (context)=>{
                                console.log(context)
                            }
                        }
                    </myContext.Consumer>
                </myContext.Provider>   
                <br/>
                <Father msg={this.state.msg}></Father>
            </div>
        )
    }
}

确实在子组件当中调用context的结果

项目开始

项目创建

创建项目库

创建项目

create-react-app xumobile

安装依赖

npm i events [email protected] axios -S

调整结构

修改端口

封装axios

import { Component } from 'react'
import axios from 'axios'

axios.defaults.baseURL ="/api"

axios.interceptors.response.use(response=>{
    return response.data
})

Component.prototype.$http = axios

export default axios

设置跨域

npm install --save-dev [email protected]

 

配置路由

猜你喜欢

转载自blog.csdn.net/qq_48469083/article/details/121385415