React函數(shù)組件useContext useReducer自定義hooks
一、hooks(useContext)
接收一個(gè) context 對(duì)象(React.createContext 的返回值)并返回該 context 的當(dāng)前值。當(dāng)前的 context 值由上層組件中距離當(dāng)前組件最近的 <MyContext.Provider> 的 value prop 決定。
新建useContext.js函數(shù)組件,寫入如下代碼:
import React, { useEffect, useState, useContext } from 'react'
import axios from 'axios'
import '../css/middlecp.css'
const GlobalContext = React.createContext(); // 創(chuàng)建context對(duì)象
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>觀眾評(píng)分:{grade}</div>
</div>
}
function FilmDetail() {
const value = useContext(GlobalContext)
return (
<div className="filmdetail">
{value.info}
</div>
)
}
二、hooks(useReducer)
useState 的替代方案。它接收一個(gè)形如 (state, action) => newState 的 reducer,并返回當(dāng)前的 state 以及與其配套的 dispatch 方法。
新建useReducer.js組件,寫入代碼:
import React, { useReducer } from 'react'
export default function UseReducer() {
// 處理函數(shù)
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;
}
}
// 外部對(duì)象
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使用跨級(jí)通信。(hooks中自帶的,后面redux不用這么麻煩) 修改useReducer.js組件代碼為如下:
import React, { useReducer, useContext } from 'react'
// 處理函數(shù)
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;
}
}
// 外部對(duì)象
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
當(dāng)我們想在兩個(gè)函數(shù)之間共享邏輯時(shí),我們會(huì)把它提取到第三個(gè)函數(shù)中。 必須使用use開頭。(實(shí)際上就是將獨(dú)立的邏輯函數(shù)抽離出來封裝) 新建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會(huì)執(zhí)行函數(shù)并返回執(zhí)行后的結(jié)果
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>
)
}
效果:

可以看到我們這個(gè)影院的篩選功能還是正常,但是看代碼的話,邏輯更加的清晰了。
以上就是React函數(shù)組件useContext useReducer自定義hooks的詳細(xì)內(nèi)容,更多關(guān)于React hooks函數(shù)組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React實(shí)現(xiàn)雙滑塊交叉滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)雙滑塊交叉滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
解決React報(bào)錯(cuò)Parameter 'props' implicitly&nb
這篇文章主要為大家介紹了React報(bào)錯(cuò)Parameter 'props' implicitly has an 'any' type的解決處理方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
react后臺(tái)系統(tǒng)最佳實(shí)踐示例詳解
這篇文章主要為大家介紹了react后臺(tái)系統(tǒng)最佳實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例
下面小編就為大家?guī)硪黄猺eact native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
基于Webpack4和React hooks搭建項(xiàng)目的方法
這篇文章主要介紹了基于Webpack4和React hooks搭建項(xiàng)目的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02
如何應(yīng)用?SOLID?原則在?React?中整理代碼之開閉原則
React?不是面向?qū)ο?,但這些原則背后的主要思想可能是有幫助的,在本文中,我將嘗試演示如何應(yīng)用這些原則來編寫更好的代碼,對(duì)React?SOLID原則開閉原則相關(guān)知識(shí)感興趣的朋友一起看看吧2022-07-07
關(guān)于react-router-dom路由入門教程
這篇文章主要介紹了關(guān)于react-router-dom路由入門教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03

