React之 常见的hooks

前面是类组件,今天是函数式组件

函数式组件的特点

  • 没有状态

  • 没有生命周期

  • 没有this

  1. useState

src>index.js

import React from 'react'
import { createRoot } from 'react-dom/client'
import './css/common.css'  //引入公共样式
import App1 from './App1' //引入模块

const root = createRoot(document.getElementById('root'))
root.render(
    <div>
        <App1/>
    </div>
)

src>css>common.css 公共样式文件

*{
    padding:0;
    margin:0;
    list-style:none;
}

src>App1.js

import React, { useState } from 'react'
function App1() {
    //useState(0)中的0是num的初始值,后面修改num的值需要通过setNum
    const [num, setNum] = useState(0)
    return (
        <div>
            <h3>num: {num}</h3>
        </div>
    )
}

*注意,Hooks的API只能在函数内的最外层声明

if(true){
    const [num, setNum] = useState(0)
}
//报错,不能写在条件判断语句中
  1. useEffect

将App1改为

import React, { useState, useEffect } from 'react'
function App1() {
    // useState(0) 中的0是num的初始值
    const [num, setNum] = useState(0)
    const [num1, setNum1] = useState(0)
    // 检测视图更新
    useEffect(() => {
        console.log('useEffect,视图更新了');
    },[num])
    //1  相当于componentDidMount:
    // 第一次挂载一定会打印一次
    //2  相当于componentDidUpdate:
    // 回调的数组不写,默认所有数据更新都会打印
    // 回调的数组写了对应的变量,则变量改变才打印
    // 回调的数组为空,则·不检测更新

    return (
        <div>App1
            <h3>num: {num}</h3>
            <button onClick={() => setNum(num + 1)}>累加</button>
            <h3>num1: {num1}</h3>
            <button onClick={() => setNum1(num1 + 1)}>累加</button>
        </div>

    )
}
export default App1
  1. useReducer 和useRef

类似于redux

src>App2.js:

import React, { useRef, useReducer } from 'react'
import './css/app2.css'
// 1、定义一个reducer
function texReducer(state, action) {
    let newState = JSON.parse(JSON.stringify(state))
    switch (action.type) {
        case 'change_fn':
            newState.texVal = action.value
            return newState
        case 'publish_fn':
            if (action.value) {
                newState.list.unshift(action.value)
                newState.texVal  = '' //数据初始化
            } else {
                alert('请输入非空的内容')
            }
            return newState
        case 'del_fn':
            newState.list.splice(action.value, 1)
            return newState

        default:
            break
    }
}

function App2() {
    // 2、使用reducer并解构出state与dispatch,   { texVal: '写点什么', list: [] }表示state的默认数据
    const [state, dispatch] = useReducer(texReducer, { texVal: '写点什么', list: [] })
    // 3.useRef获取元素
    const element = useRef(null)
    const changeFn = () => {
        // 4.current指向ref挂载的dom元素
        console.log(element.current.value);
        // 5.dispatch调用 
        dispatch({ type: 'change_fn', value: element.current.value })
    }
    const publishFn =() => { dispatch({ type: 'publish_fn', value: state.texVal }) }
    return (
        <div className="box">
            <div className='txtbox'>
                <div className='title'>有什么新鲜事想告诉大家?</div>
                <textarea name="" id="txta" ref={element} cols="30" rows="10" placeholder='请在此输入内容' value={state.texVal}
                    onChange={changeFn}>
                </textarea>
                <div className='foot'>
                    <div></div>
                    <div className='btn' onClick={publishFn}>发布</div>
                </div>
            </div>
            <ul className="content">
                {
                    state.list.map((item, index) => {
                        return <li key={index} className='foot'><div className='li-con'>{item}</div> <div className='btn' onClick={() => { dispatch({ type: 'del_fn', value: index }) }}>删除</div></li>
                    })
                }
            </ul>


        </div>
    )

}
export default App2

记得在index.js引入组件App2

src>css>app2.css 样式文件

html {
    background-color: #eee;
}

.title {
    color: #333;
    height: 50px;
    line-height: 50px;
}

.box {
    width: 100%;
    height: 100%;

}

.txtbox {
    background-color: #fff;
    width: 800px;
    padding: 10px;
    margin: 100px auto 10px;
}


#txta {
    width: 800px;
    height: 100px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    outline-color: #ff8140;
    padding: 8px;

}

.content {
    width: 800px;
    padding: 10px;
    margin: 0 auto;
    background-color: #fff;
}

.foot {
    display: flex;
    justify-content: space-between;
    height: 40px;


}

.btn {
    width: 10%;
    text-align: center;
    height: 28px;
    line-height: 28px;
    margin: 6px 0;
    background-color: #ff8140;
    border-radius: 4px;
    color: #fff;

}

ul li {
    height: 50px;
    line-height: 50px;
 
    border-bottom: 1px solid #999;
}

.li-con {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 90%;
    
}

猜你喜欢

转载自blog.csdn.net/CSSAJBQ_/article/details/128965123