react中函数式组件React Hooks

React Hooks

函数式组件

使用hooks理由

  1. 高阶组件为了复用,导致代码层级复杂
  2. 生命周期的复杂
  3. 写成functional组件,无状态组件,因为需要状态,又改成了class,成本高

在16.8版本之前函数式组件无法写状态所以一般只能用class组件成本比较高代码嵌套比较深,并且钩子函数(生命周期相对来说过于复杂)在16.8之后出了函数式组件的状态后,很好的解决了这些弊端。

useState

在之前版本中函数式组件是不支持状态的为了让函数式组件更好的支持状态,可以利用useState

const [name,setName] = useState("Riven")

主要利用这个useState的方法 也是一个数组它有个值一个是Riven,另一个是修改这个状态的方法f()你可以打印一下自己查看console.log(useState(“Riven”)) 如上代码就是将这个状态和这个修改状态的方法给解构出来这样就可以访问到状态,并且进行修改了

// rcc => react component class
// rfc => react component function

import React,{useState} from 'react'
//利用useState让函数式组件支持状态

function App(){
    console.log(useState("Riven"));
//不支持状态
    const [name,setName] = useState("Riven")
    const [age,setAge] = useState(25)
    return(
        
app----{name}---{age}
) } export default App

以上就是函数式组件的基本写法了你肯定有许多问题?函数式组件的生命周期呢?函数式组件的传值呢通信呢?没有类组件的写法这些应该怎么写呢?

请随我继续往后看

todolist小案例(函数式组件)

首先怎么获取input框中的value值呢?

这里我们有两种方法和类组件差不多

  1. 就是利用onChage事件
import React,{useState} from 'react'

function App(){
    const [text, setText] = useState("")
    return(
        
{ // console.log(ev.target) setText(ev.target.value) }} />
) } export default App
  1. 利用ref

这种方法较为复杂需要利用useRef

import React,{useState,useRef} from 'react'

const mytext = useRef(null)

       {
                // console.log(ev.target)
                setText(ev.target.value)
            }} ref={mytext} />

访问的时候可以直接通过mytext.current.value得到value值

import React,{useState,useRef} from 'react'

function App(){
    const [text, setText] = useState("")
    const mytext = useRef(null)
    return(
        
{ // console.log(ev.target) setText(ev.target.value) }} ref={mytext} />
) } export default App
完整的todolist

需要注意学习的地方

  • input框value值获取

  • 怎么让进行添加

  • 怎么让添加完成后输入框的value值清空

  • 怎么进行删除

import React,{useState,useRef} from 'react'

function App(){
    const [text, setText] = useState("")
    const [list,setList] = useState(["111","222","333"])
    const mytext = useRef(null)


    //删除函数只是想写在外面
  const  handledelclick = (index)=>{
        var newlist = [...list]
        newlist.splice(index,1)
        setList(newlist)
    }


    return(
        
{ // console.log(ev.target) setText(ev.target.value) }} ref={mytext} value={text} /> { list.map((item,index)=>
  • {item}
  • ) }
    ) } export default App

    useEffect

    在函数式组件中我们没有生命周期useEffect类似生命周期但不是生命周期

    我们把数据请求放在函数组件的哪里呢?

    首先需要知道useEffect接收两个参数,第一个是处理函数,第二是依赖

    第一个参数相当于一旦创建就会执行。

    如果第二个参数传入的依赖状态改变也会自动执行

    如果第二个参数传入的依赖状态为空就相当于值会走一次

    如果不传任何状态改变都会触发第一个处理函数的执行

    return 出来的这个函数只有销毁的时候才会执行

        useEffect(()=>{
            console.log("创建");
            var id = setInterval(()=>{
                console.log(111);
            },2000)
            return ()=>{
                console.log("销毁")
                clearInterval(id)
            }
        },[])
    
    
    

    下来看一个简单的案例

    import React,{useState,useEffect} from 'react'
    
    const Child = ()=>{
        useEffect(()=>{
            console.log("创建");
            var id = setInterval(()=>{
                console.log(111);
            },2000)
            return ()=>{
                console.log("销毁")
                clearInterval(id)
            }
        },[])
        return(
            
    Child
    ) } const App = ()=>{ //useEffect(处理函数,[依赖]) const [text, setText] = useState("1111") const [age, setAge] = useState(25) // useEffect(()=>{ // console.log("创建或者更新的时候执行") // },[text]) //传入空数组相当于cdm //[text] 只有text的改变才会执行一次 //第二参数不传表示任何状态改变都会重新执行 return(
    App ----{text}
    {age} { age===25? : null }
    ) } export default App

    在实际应用中函数式组件会自动传一个参数props 这样我们就可以访问到props里面的属性了

    props.match.params.myid
    props.history.goBack()

    import React,{useState,useEffect} from 'react'
    import { PageHeader} from 'antd';
    import axios from 'axios'
    
    const Preview = (props)=>{
        const [title, settitle] = useState("")
        const [content, setcontent] = useState("")
        const [category, setcategory] = useState([])
    
        useEffect(()=>{
            axios.get(`http://localhost:8000/articles/${props.match.params.myid}`).then(res=>{
                console.log(res.data)
                let {title,content,category} = res.data
                settitle(title)
                setcontent(content)
                setcategory(category)
            })
    
        },[props])
    
    
    
    
        return (
            
    { // console.log("back",this.props.history) props.history.goBack()//返回上一个页面 }} //返回按钮 title={title} subTitle={category.join("/")} />
    ) } export default Preview

    useCallback

    防止因为组件重新渲染,导致方法被重新创建 ,起到缓存作用; 只有第二个参数 变化了,才重新声明一次

    也就是只需要当需要某个状态改变的时候才让函数执行一次

    import React,{useState,useCallback} from 'react'
    
    export default function App() {
        const [text,settext] = useState("1111")
        const test = useCallback(
            () => {
                console.log(text)
            },
            [text],
        )
        test()
        return (
            
    App-{text}
    ) }

    useContext useReducer

    首先这两个都是用来在函数式组件中进行非父子通信的

    首先需要创建一个GlobalContext 用来包裹这些生产者的

    import React from 'react'
    const GlobalContext = React.createContext()
    
    export default GlobalContext
    
    

    然后引入

    import GlobalContext from './store'
    
    

    总体代码如下

    import React,{useReducer,useContext} from 'react'
    import GlobalContext from './store'
    import reducer from './store/reducer'
    import axios from 'axios'
    
    const Child1 = ()=>{
        // useContext(GlobalContext)
        // console.log(useContext(GlobalContext))
        let {state,dispatch} = useContext(GlobalContext)
       
        return (
            
    child1-----{state.text}
    ) } const Child2 = ()=>{ let {state,dispatch} = useContext(GlobalContext) return (
    Child2----{state.text} { state.list.map(item=>
  • {item.title}
  • ) }
    ) } const App = ()=>{ const [state,dispatch] = useReducer(reducer,{ isShow:true, list:[], text:"我是公共的状态" }) //[公共的状态,改变公共状态的方法] return ( ) } export default App

    这里需要注意

       const [state,dispatch] = useReducer(reducer,{
            isShow:true,
            list:[],
            text:"我是公共的状态"
        })  //[公共的状态,改变公共状态的方法]
    
    

    这块useReducer(reducer) 其实相当于一个数组里面有两个值一个是公共的状态另外一个改变公共状态的方法

    访问的时候可以通过usecontext(GlobalContext) 里面有两个值一个为state,一个为dispatch

    const Child1 = ()=>{
        // useContext(GlobalContext)
        // console.log(useContext(GlobalContext))
        let {state,dispatch} = useContext(GlobalContext)
       
        return (
            
    child1-----{state.text}
    ) }

    异步也差不多

    const Child2 = ()=>{
        let {state,dispatch} = useContext(GlobalContext)
        return (
            
    Child2----{state.text} { state.list.map(item=>
  • {item.title}
  • ) }
    ) }

    reducer文件

    const reducer = (prevstate,action)=>{
        let {type,payload} = action
        switch(type){
            case "Change_text":
                //深复制老状态,返回新状态
                // prevstate.text
                // var newstate = {...prevstate}
    
                return {
                    ...prevstate,
                    text:payload
                } // immutable
    
            case "Change_list":
                return {
                    ...prevstate,
                    list:payload
                }
                default:
                return prevstate
        }
       
        
    }
    
    export default reducer
    

    函数式组件的父子通信问题

    这个和类组件差不多,只不过是函数式组件会自动传一个参数props这样就可以直接访问到props里面的属性了

    父传子(属性)

    子传父(回调函数)

    // 父子通信 ,靠属性
    // 父->子 , 属性
    // 子->父 , callback( 属性传过去一个回调函数)
    
    import React,{useState} from 'react'
    
    const Navbar = (props)=>{
        console.log(props)
        return 
    navbar-{props.myname}
    } const Sidebar = ()=>{ return
    Sidebar
    • 111111
    • 222222
    • 333333
    } const Child = (props)=>{ return
    child --{props.children}
    } export default function App() { const [show, setshow] = useState(false) return (
    { console.log("父组件中调用") setshow(!show) }}/> { show? :null }
    child-11111111
    child-22222222
    ) }

    你可能感兴趣的:(react)