文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React函数组件useContextuseReducer自定义hooks

2022-11-13 14:15

关注

一、hooks(useContext)

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

新建useContext.js函数组件,写入如下代码:

import React, {  useEffect, useState, useContext } from 'react'
import axios from 'axios'
import '../css/middlecp.css'
const GlobalContext = React.createContext(); // 创建context对象
export default function UseContext() {
    const [filmList, setFilmList] = useState([])
    const [info, setInfo] = useState('')
    useEffect(() => {
        axios.get('/data.json').then(res => {
            console.log(res.data.data.films)
            setFilmList(res.data.data.films)
        }, err => {
            console.log(err)
        })
    }, [])
    return (
        <GlobalContext.Provider value={{
            info: info,
            changeInfo: (value) => {
                setInfo(value)
            }
        }}>
            <div>
                {
                    filmList.map(item => {
                        return <FilmItem key={item.filmId} {...item}></FilmItem>
                    })
                }
                <FilmDetail></FilmDetail>
            </div>
        </GlobalContext.Provider>
    )
}
function FilmItem(props) {
    let { name, poster, grade, synopsis } = props
    const value = useContext(GlobalContext)
    console.log(value)
    return <div className="filmitem" onClick={() => {
            value.changeInfo(synopsis)
        }}>
            <img src={poster} alt={name}></img>
            <h4>{name}</h4>
            <div>观众评分:{grade}</div>
        </div>
}
function FilmDetail() {
    const value = useContext(GlobalContext)
    return (
        <div className="filmdetail">
            {value.info}
        </div>
    )
}

二、hooks(useReducer)

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。

新建useReducer.js组件,写入代码:

import React, { useReducer } from 'react'
export default function UseReducer() {
  // 处理函数
  const reducer = (prevState, action) => {
    console.log(prevState, action)
    let newState = {...prevState}
    switch(action.type) {
        case 'minus':
            newState.count--
            return newState;
        case 'add':
            newState.count++
            return newState;
        default:
            return newState;
    }
  } 
  // 外部对象
  const intialState = {
    count: 0
  }
  const [state, dispatch] = useReducer(reducer, intialState)  
  return (
    <div>
        <button onClick={() => {
            dispatch({
                type: "minus"
            })
        }}>-</button>
            {state.count}
        <button onClick={() => {
            dispatch({
                type: "add"
            })
        }}>+</button>
    </div>
  )
}

效果:

三、hooks(useContext搭配useReducer使用)

hooks中useContext搭配useReducer使用跨级通信。(hooks中自带的,后面redux不用这么麻烦) 修改useReducer.js组件代码为如下:

import React, { useReducer, useContext } from 'react'
// 处理函数
const reducer = (prevState, action) => {
    console.log(prevState, action)
    let newState = {...prevState}
    switch(action.type) {
        case 'child2':
            newState.a = '改变后的a'
            return newState;
        case 'child3':
            newState.b = '改变后的b'
            return newState;
        default:
            return newState;
    }
  } 
// 外部对象
const intialState = {
    a: 'aaaaa',
    b: 'bbbbb'
}
const GlobalContext = React.createContext()
export default function UseReducer() {
  const [state, dispatch] = useReducer(reducer, intialState)  
  return (
    <GlobalContext.Provider value={
        {
            state,
            dispatch
        }
    }>  
        <div>
            <Child1></Child1>
            <Child2></Child2>
            <Child3></Child3>
        </div>
    </GlobalContext.Provider>
  )
}
function Child1() {
    const {dispatch} = useContext(GlobalContext)
    return (
        <div>
            <button onClick={() => {
                dispatch({
                    type: 'child2'
                })
            }}>改变child2</button>
            <button onClick={() => {
                dispatch({
                    type: 'child3'
                })
            }}>改变child3</button>
        </div>
    )
}
function Child2() {
    const {state} = useContext(GlobalContext)
    return (
        <div>
            {state.a}
        </div>
    )
}
function Child3() {
    const {state} = useContext(GlobalContext)
    return (
        <div>
            {state.b}
        </div>
    )
}

效果:

四、自定义hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。 必须使用use开头。(实际上就是将独立的逻辑函数抽离出来封装) 新建useCustom.js,写入代码:

import React, { useEffect, useMemo, useState } from 'react'
import axios from 'axios'
function useCinemaList() {
    const [cinemaList, setCinemaList] = useState([])
    useEffect(() => {
        axios({
            url: 'https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018',
            method: 'get',
            headers: {
                'X-Client-Info':' {"a":"3000","ch":"1002","v":"5.2.0","e":"1646314068530784943341569"}',
                'X-Host': 'mall.film-ticket.cinema.list'
            }
        }).then((res) => {
            console.log(res.data)
            setCinemaList(res.data.data.cinemas)
        }).catch((err) => {
            console.log(err)
        })
      },[])
      return {
        cinemaList
      }
}
function useFliter(cinemaList, text) {
    const getCinemaList = useMemo(() => cinemaList.filter(item => item.name.toUpperCase().includes(text.toUpperCase()) || 
  item.address.toUpperCase().includes(text.toUpperCase())), [cinemaList, text]) // useMemo会执行函数并返回执行后的结果
    return {
        getCinemaList
    }
}
export default function UseCustom() {
  const [text, setText] = useState('')
  const {cinemaList} = useCinemaList()
  const {getCinemaList} = useFliter(cinemaList, text)
  return (
    <div>
        <input value={text} onChange={(event) => {
              setText(event.target.value)
            }}></input>
            {
                getCinemaList.map((item) => 
                <dl key={item.cinemaId}>
                    <dt>{item.name}</dt>
                    <dd>{item.address}</dd>
                </dl>
                )
            }
    </div>
  )
}

效果:

可以看到我们这个影院的筛选功能还是正常,但是看代码的话,逻辑更加的清晰了。

以上就是React函数组件useContext useReducer自定义hooks的详细内容,更多关于React hooks函数组件的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯