React hooks函数组件
你华还是你华 人气:0一、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> ) }
效果:
可以看到我们这个影院的筛选功能还是正常,但是看代码的话,逻辑更加的清晰了。
加载全部内容