navigation

[Deep 01] Execution context [Deep 02] Prototype chain [Deep 03] Inheritance [Deep 04] Event loop [Deep 05] Curri Bias function [Deep 06] Function memory [Deep 07] Implicit conversions and operators [Deep 07] Browser caching mechanism (HTTP caching mechanism) [Deep 08] Front-end security [Deep 09] Deep copy [Deep 10] Debounce Throttle [Deep 10] Front-end routing [Deep 12] Front-end modularization [Deep 13] Observer mode Publish subscribe mode Bidirectional data binding [Deep 14] Canvas [Deep 15] webSocket Webpack HTTP and HTTPS CSS- Interview Handwriting Promise

[react] Hooks

[Deployment 01] Nginx [Deployment 02] Docker deployVue project [Deployment 03] gitlab-CI

[source code – Webpack01 – precompiler] AST abstract syntax tree [source code – Webpack02 – Precompiler] Tapable [source code – Webpack03] hand written webpack-compiler simple compilation process [source code] Redux React-redux01 [source] Axios [source] vuex [source -vue01] Data reactive and initialize render [source -vue02] Computed responsive – Initialize, access, Update Procedure [source -vue04] Watch Listening properties – Initialize and update [source -vue04] vue. set and vm.$set [source -vue05] vue.extend

Vue. NextTick and VM.$nextTick

A practical summary of react-hooks

UseState useEffect useLayoutEffect useCallback useMemo useRef (useImperativeHandle useImperativeHandle (useRef)) UseReducer useContext Context React.memo -- useFetch -- how to encapsulate a useFetch hooks parent component how to obtain the child component method 'useImperativeHandle' ` forwardRef ` - review: js handwritten call the comments in the specification, applay, bind logical operators && | |Copy the code

useState

  • function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>]
useState function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>] type Dispatch<A> = (value: A) => void; type SetStateAction<S> = S | ((prevState: S) => S); - Parameter - Parameter is a value or function - When parameter is a function, the return value is used as the initial value (used when the initial value requires complex operations) - This function is executed only once during the initial render to get the initial state. In future component rendering, it is not called again, thus skipping the expensive operation. !!!!!!!!!! - Return value - The return value is an array - First member: returns the set state - Second member: Setter function (essentially a dispatcher, underneath a useReducer) - The argument to this function can be a value, or a prevState signed (prevState: S) => S function - that is, return a state value and a function to update the state - Note - call hook only at the top level, not in loop, condition, nested function useState(), in multiple calls to useState(), the call order between renders must be the same. - Why call ??????? sequentially at the top level, but not in loops, conditions, nesting Because each internal state is maintained in a queue (like an array) - and the state in the queue corresponds to the setter function one to one, the one-to-one relationship can be changed in the above three cases, resulting in incorrect expectations -!! A closure is a function that captures variables from an external scope. - Closures (e.g. event handlers, callers) may capture state variables from the function component scope. Because state variables change between renderings, closures should capture variables with the latest state value. Otherwise, if the closure captures out-of-date state values, you may run into out-of-date state problems. - Complex states - When there are multiple states for the same task, or when there are too many states, it is recommended to use useReducer - rerender about the React component - class to rerender: Render (), willmout, dimount, etc. Re-execute the entire component function - Think - when the function is finished, all memory will be freed, and the variables declared in the function will also be freed. How can useState save state ??????? - Or, why does useState return the remembered state ???? each time it rerenders UseState uses closures to create a state of the current function component inside a function. And provides a method to modify the state. Instance -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - (1) example 1 - outdated state - setCount parameter is the value and function of the difference between < div onClick = {() = > setTimeout (() = > setCount (count + 1), 3000)}> ----------- // Execute the timer by clicking multiple times within 3 seconds, but always count =1. <div onClick={() => setTimeout(() => setCount(count => count+1), 3000)}> Will record the value of each click click execute timer, the set function parameter is a function of < / div > < div > {count} < / div > -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - (2) example 2 - if it is the same reference, Const [isReRender, setIsReRender] = useState({render: true}); -setisrerender (() => ({render: True})) -------- will re-render because it is a new object with different references - isrerender. render = false; SetIsReRender (isReRender) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- not to render, assignment after the comparison, The reference remains unchanged ------------------ (3) Example 3 - the state returned by useState remains the same throughout the life cycle, so it can be used to fix a reference to a variable, Const [a] = useState(0); // Note that this only uses the assignment value state, without changing the function ------------------ (4) Example 4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! function CaseOne() { const [count, setCount] = useState(0); UseEffect (() => {setInterval(() => {console.log(count, 'in') setCount(count+1) Each time the timer is executed, it uses the count that was declared and assigned on the first execution. Count is the count in the closure that was first rendered. The value of count is always 0. }, 1000)}, []) console.log(count, 'out') return (<div style={{background: 'yellow'}} > < div > classic use - state < / div > < / div >)} resolution: 1. The initial argument to useState() is only assigned to the count variable the first time it is executed, and subsequent renderings have no effect. 2. Subsequent render will use the return value of the last setCount. First render - useState(0) execute, return [0, setCount => 0-1s after the timer execute, form the closure, the variable count in the closure is 0, SetCount (0+1) = 0; setCount(0+1) = 0; setCount(0+1) = 0; The timer is executed again, and the count is still referenced by the first execution. The resulting closure's count is 0, setCount(0+1) - Note: The second setCount and the first setCount are both 0+1, which means that the arguments have not changed. In this case, React will not be rerendered, i.e. there will be no third render and the outer count will not be printed, Keep 1 ------------------ (5) Example 5 - useState can be used to cache a variable of a reference type if it is a value of a primitive type, which cannot be modified because it is const. Function CaseTwo() {const [a] = useState({count: Let const [b, setB] = useState(0) return (<div style={{background: }}> <div>CaseTwo</div> <div onClick={() => {a.ount = 22; SetB (b => b+1) // re-render}}> click re-render </div> <div>{a.count}</div> // print 22 <div>{b}</div> // print 10, each time it is reinitialized. To fix this value, use useRef !!!!!!!!!!! <div>{c}</div> </div> ) }Copy the code

Classic example: juejin.cn/post/684490…

Juejin. Cn/post / 684490…

Mp.weixin.qq.com/s/Bo0Q6FDn4…

Analytic: imweb. IO/topic / 5 c7d5…

UseState source: juejin.cn/post/684490…

Introduction: juejin.cn/post/684490…

useEffect

  • Execute side effect hooks
  • What are side effects: Side effects except for unexpected logic related to rendering the UI(When the DOM has rendered the executed UI-independent logic)
useEffect function useEffect(effect: EffectCallback, deps? : DependencyList): void; - type EffectCallback = () => (void | (() => void | undefined)); - type DependencyList = ReadonlyArray<any>; - First argument: function - each time after render, the side effect is executed, and the last side effect is cleared - the return value of this function is the clear function (the last side effect is cleared) - second argument: Array - when one of these dependencies is updated, the effect will regenerate a new side effect and execute the side effect - if there is no update, it will not execute. - If the second argument is not passed, there are no dependencies, then it will be executed after each render - Note: if the second argument is an empty array [] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - If an empty array is passed, the useEffect callback is executed only once, similar to componentDidMount(). - If an empty array is passed, the useEffect callback is executed only once, similar to componentDidMount(). So the Effect callback is no longer performed - the useEffect callback is only performed once, not useEffect only once, useEffect is performed after each rendering - the dependency comparison, it's just a simple comparison of whether the values or references are equal - so - obviously, UseEffect can mimic (didMount, didUpdate), return value can mimic (willUnmount) - What are the side effects - any logic that has nothing to do with rendering the UI is a side effect - and then after the DOM is rendered, I'm going to do another piece of logic, The other logic in this paragraph is the timing of the useEffect side effect: - useEffect -seteffect is executed after each rendering is completed. This is similar to componentDidMount, componentDidUpdate, and componentWillUnmount. 1. It is recommended that all states used in useEffect should be written to dependent arrays, whether they refer to underlying type values, objects or even functions. 2. UseEffect's first argument function, which returns a function, is the cleanup function 3. -useEffect's first argument function, if it returns a function, that function is the cleanup function (clears some side effects, such as timers, etc.) -Timing of execution: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - apply colours to a drawing for the first time, will not remove function to perform, so 31 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (timer, only 132 printed together) - the second rendering, the rendering is finished, executed immediately clear function, then perform Effect function callback function, 31 321 321 321 const [count, setCount] = useState(0); useEffect(() => { const timer = setInterval(() => { console.log('1=======') setCount(count+1) }, 1000) return () => { console.log('2=======') clearInterval(timer) } }, [count]) console.log('3=======')Copy the code

2021/01/08 useEffect Supplementary knowledge Summary

UseEffect supplement

  • UseEffect Function signature
    • function useEffect(effect: EffectCallback, deps? : DependencyList): void
      • type EffectCallback = () => (void | (() => void | undefined))
      • type DependencyList = ReadonlyArray<any>
  • It means to sign in person
    • useEffect(() => { return Cleanup(){… }}, […]. )
    • The first argument: is a function that can also return a Cleanup function
    • The second argument: is an array of dependencies
  • The magic of useEffect !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    • UseEffect first argument function
      • UseEffect is executed after rendering is complete and therefore does not block rendering
        • Execute before rendering (UseLayoutEffect synchronization hook )
          • What about when the render performs some tasks? You can use useLayoutEffect
        • Execute after rendering (UseEffecct asynchronous hook )
          • UseEffect is executed after rendering and does not block rendering, improving performance
      • Before useEffect executes, the last useEffect Cleanup function (if any) is executed.
        • UseEffect is executed only once
        • UseEffect does not execute the Cleanup function the first time it is executed
        • Run the last useEffect Cleanup function of the component when it is uninstalled
      • When the component is destroyed, the last useEffect Cleanup function is executed
    • The second argument to useEffect – the dependency array
      • The dependency array controls whether the useEffect() hook function is fired
      • UseEffect is equivalent to (componentDidMount) (componentDidUpdate) (componentWillUnmount) three life cycles
        • Simulate componentDidMount(only during the mount phase)
          • useEffect(()=>{}, [])
          • When the dependent array is empty, the Cleanup function, if there is one, will not be executed after the first time and will not be executed until the component is destroyed
        • Simulate componentDidUpate(not executed in mount phase, executed in update phase)
          • With a flag bit, isDidUpdate defaults to false, then useEffect is not executed the first time, set it to true, and is executed the second time
          • UseEffect (() => {if(isDidUpdate){// compenntDidUpdate phase execution code}; setIsDidUpdate(true) })
      • How are dependent arrays aligned? , mainly through object. is to do the comparison
        • So, if you rely on the array member being a reference type (array, object, function), you need to use useMemo() and useCallbak()
        • UseMemo (() => object, [dependent array])
        • UseCallback (fn, [dependency array])
        • UseMemo is used to cache any type of data, including functions
        • namelyUseMemo (() => fn, []) = useCallback(fn, [])
      • UseEffect (() -> {setters ()}, [dependencies]);
        • There is no need to manually memoizaton the setter functions through useMemo or useCallback because react internally memoizaton the setter functions each time
    • One more note
      • UseEffect (async() => {}, [dependency]
      • This is because: the useEffect signature indicates that the first argument function either returns no value or returns a Cleanup function, while the aysnc function returns a promise object. This is strongly not recommended

Summarize the useState and useEffect

  • UseState and useEffect are added to the Hook (The list)
  • UseEffect will also be added in a (The queue), which is useEffect’s first argument function. After rendering is complete, the Effect callback function in the queue is called in turn
  • On why hooks must be placed in component headers? Can’t be used in a loop, nested, conditional statement?
    • This is primarily to ensure that the order in which you call the hooks is consistent each time the function component is executed
    • Because looping, nesting, and conditional statements are dynamic statements, it is possible that each function component may not call hooks in the same order, invalidating the data recorded in the linked list

Juejin. Cn/post / 684490… Juejin. Cn/post / 684490…

useLayoutEffect

  • Effect is called synchronously after all DOM changes. You can use it to read the DOM layout and trigger a rerender synchronously. The update plan inside the useLayoutEffect is synchronously refreshed before the browser performs the drawing.
  • UseLayoutEffect is the same as componentDidMount and componentDidUpdate. Note that only the call time is the same
  • SeLayoutEffect is synchronous, while useEffect is asynchronous
  • UseLayoutEffect can solve the problem of screen bouncing
useEffect function App2 () { const [count, setCount] = useState(0) useEffect(() => { if (count===0) { setCount(count => Math.random()) } }, [count]) return (<div> <div onClick={() => setCount(count => 0)}> </div> {count} </div>) SetCount (count => 0), useEffect, setCount(count => math.random ()) To render get random Numbers -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- useLayoutEffect function App2 () {const [count, setCount] = useState(0) useLayoutEffect(() => { if (count===0) { setCount(count => Math.random()) } }, [count]) return (<div> <div onClick={() => setCount(count => 0)}> </div> {count} </div>)} 1. SetCount (count => 0), reset render, the browser does not complete the render, 3. UseLayoutEffect execution, no logic, rendering random numbersCopy the code

useCallback

  • Caching functions (or caching function variables), (or fixed function references)
UseCallback - fixed function reference, i.e. cache function - function useCallback<T extends (... args: any[]) => any>(callback: T, deps: DependencyList): T; - Arguments: - First argument: callback function - Second argument: Dependencies - return value - Return value is a function of type T - description - normally, functions are redeclared when the component is rerendered - but functions wrapped in useCallback are 'equivalent' to redeclared only when the dependencies change, if not, Const a = useCallback(() => {... }, []) - In this case A is never redeclared because its dependency is null - performance optimization !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Memo: the memo will only be reacted when the props are changed, depending only on the props passed in - when the functions are included in the props, the reference to the functions can be controlled using useCallback. UseCallback controls whether functions in props change !!!!!! Example (1) Using React.Memo as a performance optimization parent:  function UseCallback() { const [count, setCount] = useState(0) const [color, SetColor] = useState('yellow') const callBackChangeColor = useCallback(() => {// The callBackChangeColor function updates only depending on the color change // If the color is not updated, Const index = math.floor (math.random ()*4) setColor(['black', 'white', 'blue', 'green', 'Purple'][index]) }, [color]) return ( <div style={{background: '#FF4500', padding: '20px', margin: '10px 0'}}> <div style={{color}}>USE_CALLBACK</div> <div onClick={() => setCount(count => count+1)}> Parent component change count</div> / <div>{count}</div> <ChildUseCallback setColor={callBackChangeColor} /> // child </div>)} Const ChildUseCallback = React. Memo (({setColor}) => {// React. Memo only depends on setColor changes const changeColor = () => { Return (<div style={{background: '#FA8072'}}> <div>CHILD_USE_CALLBACK</div> <div onClick={changeColor}>Copy the code

useMemo

  • Cache variables, similar to evaluating attributes
  • There are two things to consider when using it
    • Is the function you have to remember expensive? UseMemo should be considered only for large users
    • Is the original value returned? UseMemo is only considered if it is not a raw value
  • The ESLint Hook emits a warning when the useEffect function wants to use props that will not change again, but no longer has dependencies
    • The solution is to use useRef to anchor certain props that do not need to be changed=> Please click the link below for details
useMemo - function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T; - Parameter - The first parameter is a function, Const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]) The inner function must have a return value !!!!!!!!!!!!! - The second argument is an array or undefined, that is, the dependency - Return the value of a variable of type T  function UseCallback() { const [count, setCount] = useState(0) const [color, setColor] = useState('yellow') const [isBoolean, setIsBoolean] = useState(false) const callBackChangeColor = useCallback(() => { const index = Math.floor(Math.random()*4) setColor(['black', 'white', 'blue', 'green', 'Purple'][index]) }, [color]) const aOrBFn = () => { return isBoolean ? 'A' : } const cacheIsBoolean = useMemo(() => aOrBFn(), [isBoolean]) // useMemo // useMemo, re-execute aOrBFn if isBoolean changes, Also, if the child component has no dependent state change, do not rerender // for example: // 1. When count changes, the parent component rerenders, but the child does not depend on cont and does not want to rerender // 2. Subcomponent re-rendering depends only on the cacheIsBoolean variable and the callBackChangeColor function // 3. Return (<div style={{background: <div style={{background: <div style={{background: '#FF4500', padding: '20px', margin: '10px 0'}}> <div style={{color}}>USE_CALLBACK</div> <div onClick={() => setCount(count => count+1)}>  <div>{count}</div> <div onClick={() => setIsBoolean(boo => ! Boo)}> Parent component change => Boolean</div> // isBoolean change, <div>{isBoolean + "}</div> <ChildUseCallback setColor={callBackChangeColor} CacheIsBoolean ={cacheIsBoolean}/> // Subcomponents depend on cacheIsBoolean </div>)} Subcomponents:  const ChildUseCallback = React.memo(({setColor, CacheIsBoolean}) => {const changeColor = () => {setColor()} console.log(' child component performed ') return (<div style={{background: '#FA8072'}}> <div>CHILD_USE_CALLBACK</div> <div onClick={changeColor}>Copy the code

Where to avoid using useMemo www.infoq.cn/article/mM5…

useRef

useRef - const refContainer = useRef(initialValue); - function useRef<T = undefined>(): MutableRefObject<T | undefined>; Current property - useref. current property, which is initialized to the passed parameter (initialValue) - Return value - return a variable REF object - return ref object, (1) Function - holds any variable value that remains constant throughout the lifetime of the component (return the same REF object every time it is rendered) - that is, it can also bind DOM nodes to child components (holds any variable value including DOM nodes, Subcomponents, etc.) - equivalent to a normal property in class (2) Note - Changing the useref.current property does not trigger a rerendering of the component, similar to the property declared in class components (3) instance - Primary tests: Function UseRef() {const renderTimes = UseRef(0); Rendertimes.currentvalue ++; // Render times.currentvalue ++; // Render times.currentvalue ++; // Render time +1 const inputRef = useRef(null) renderTimes.current) // 1 2 console.log('useRef.current:', inputRef.current) // null <input /> const focus = () => { inputRef.current.focus() } return ( <div style={{background: '#FFBBFF'}}> <div>USE_REF</div> <input ref={inputRef} /> <button onClick={focus}> </button> </div>)}Copy the code

UseRef Usage scenario juejin.cn/post/684490…

useContext

  • Note: In the function component, you must use useContext to get the value of the context instance, not directly as in the class component
Function useContext<T>(context:); function useContext<T>(context:); Context<T>/*, (not public API) observedBits? : number|boolean */): T; interface Context<T> { Provider: Provider<T>; Consumer: Consumer<T>; displayName? : string; } (1) const value = useContext(MyContext); - Parameter - a context object, (return value of React.createcontext) - Return value - Current value of context - Note: The value of the context is determined by the value prop of the nearest < myContext. Provider>. - This hoos will trigger 'rerender' when the latest update of the upper layer < myContext.provider > occurs, And use the latest value - scenario - avoid data layer passing - essence - useContext is actually a <context instance in class. Consumer> or static contextType = context instance syntax sugar - useContext just lets you read the context value and subscribe to the context change --------------- example:  import React, {useContext, useState} from 'react'; Const TestContext = react.createcontext ('100') const TestContext = react.createcontext ('100') Function UseContext() {const [fontWeight, setFontWight] = useState('400') return ( <div style={{background: '#1E90FF'}}> <div>USE_CONTEXT</div> <div onClick={() => setFontWight('700')}> Change context</div> < testContext.provider Value ={fontWeight}> // The context instance provides the Provider component. The component provides the value. When the value changes, <ContextChildOne /> </ testContext.provider > </div>); function ContextChildOne() {return (<div>); <div> < ContextChildOne</div> <ContextChildTwo /> </div>)} function ContextChildTwo() {const fontWeightTwo = UseContext return (<div> <div style={{fontWeight: fontWeightTwo}}>ContextChildTwo</div> </div> ) } export default UseContext;Copy the code

What do you use context:react.docschina.org/docs/contex class component… Website useContext react.docschina.org/docs/hooks-…

Context

  • React.createContext
  • Class.contextType
  • Context.Provider
  • Context.Consumer
  • Context.displayName
Context-context provides a method of passing data between components without manually adding props for each layer of components. Note: If a component's properties need to be passed through multiple layers and only the last component needs to use the properties passed, you can use inversion of Control. Pass the entire component to be used at the end, reducing the number of props and the number of layers to pass - API 1.react. CreateContext - Create a context object, Notice objects - When React renders a component that subscribes to this context object, This component reads the current context from its nearest Provider - defaultValue only takes effect if there is no Provider match in the component tree of the component subscribed to this context. 2. Context. provider - < context. provider value={... }> -Each Context object has a Provider object component that allows consuming components to 'subscribe to changes in the Context' -provider receives a value property, Pass to consumer components - one Provider can be related to multiple consumer components - multiple providers can also be nested, with the inner layer overwriting the outer layer - Note that when the Provider's value changes, all the consuming components within it will be rerendered. !!!!!!!!!!!!!!!!! - Both the Provider and its internal Consumer components are not subject to the shouldComponentUpdate function, so consumer components can update if their ancestors quit updating. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3. Class. ContextType - ` for this. The context to consume ` - MyClass. ContextType = MyContext; // MyContextType = contextType; // MyContextType = contextType; // MyContextType = contextType; - The contextType attribute mounted on the class is reassigned to a Context object created by React.createcontext (). - This allows you to consume the value of the most recent context using this. Context. You can access it in any lifecycle, including the render function. - If you are using the experimental public Class Fields syntax, you can use the class property 'static' to initialize your contextType. class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; / * * /}} on rendering based on this value is -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 4. Context. The Consumer - React components can also subscribe to the Context changes. Context-code case: const GlobalThem = React.createcontext ({color: Function App2() {return (<div> < globalthem.provider value={{color: # ff0000; color: # ff0000; color: # ff0000; color: # ff0000; color: # ff0000; 'blue'}}> // The Provider feeds the context to the consumer component, passes the value to the consumer component, </ globalthem.provider > </div>)} function Child() {return (<div> < morat /> </div>)} The function Grandson () {return (< GlobalThem. Consumer > / / Consumer is mainly used for functional components, can use the class in the class components. ContextType packaging, // The consumer component subscribs to the context with this.context, < value => (<div> // return a component {value.color} </div>)} </ globalthem.consumer >) -------------------- 5.context. displayName - The Context object accepts a property named displayName, of type string. - React DevTools uses this string to determine what context to display. const MyContext = React.createContext(/* some value */); MyContext.displayName = 'MyDisplayName'; < myContext. Provider> // "myDisplayName. Provider" in DevTools < myContext. Consumer> //" myDisplayName. Consumer" in In the DevToolsCopy the code
  • The react react.docschina.org/docs/contex website tutorial…

React.memo

Const MyComponent = React. Memo (function MyComponent(props) {/* render props */}); - react.memo () is a higher-order component, similar to react.pureComponent (), but the memo only works on function components, not class components. There is no rerender - that is, React will skip the render component and directly reuse the results of the most recent render - that is, (function memory), cache the resulting valuesCopy the code

useReducer

useReducer const [state, dispatch] = useReducer(reducer, initialArg, init); -reducer - (state, action) => newState, accept a state and action, return a new initial value of state from the state-Initialarg -reducer, In most cases it is an object as a reasonable data type - return value - return current state and dispatch function - Usage scenario - When there are a lot of states in the component, UseReducer can aggregate various states - when data in various hierarchy components needs to be shared frequently -------------- instance: const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); // useReducer return ( <> Count: {state.count} <button onClick={() => dispatch({type: <button onClick={() => Dispatch ({type: 'increment'})}>+</button> </> ); }Copy the code

How to encapsulate a useFetch

Export function useFetch(fetchFn, fnParams={}) {const [data, setData] = useState([]) const [params, setParams] = useState(fnParams) const [isError, setIsError] = useState(false) const [isLoading, setIsLoading] = useState(false) useEffect(() => { const fetchData = async() => { setIsLoading(true) setIsError(false) try { const res = await fetchFn(params) setData(res.data) } catch(err) { setIsError(true) } setIsLoading(false) } FetchData ()}, [params]) // fetchData depends on params updates, FetchData const doFetch = (params) => {setParams(params) => {setParams(params)} return {data, isError, isLoading, DoFetch}} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - (2) version 2 In Version 1, each state performs the same side effect, Import {useState, useEffect, useReducer} from 'react'; import {FetchReducer, fetchType} from '.. /.. /store/reducers/fetch-reducer'; export function useFetch(fetchFn, fnParams={}) { const [params, setParams] = useState(fnParams) const [state, dispatch] = useReducer(FetchReducer, { data: [], isError: false, isLoading: false }) useEffect(() => { const fetchData = async() => { dispatch({type: Fetchtype.fetch_init}) // Start, dispatch => Action try {const res = await fetchFn(params) dispatch({type: Fetchtype. FETCH_SUCCESS, payload: res.data}) // Catch (err) {dispatch({type: Fetchtype.fetch_fail})}} fetchData()}, [params]) const doFetch = (params) => { setParams(params) } return {doFetch, ... } (fetch- reduc.js) export const fetchType = {FETCH_INIT: 'FETCH_INIT', FETCH_SUCCESS: 'FETCH_SUCCESS', FETCH_FAIL: 'FETCH_FAIL' } export const FetchReducer = (state, action) => { switch(action.type) { case fetchType.FETCH_INIT: return { ... state, isError: false, isLoading: true } case fetchType.FETCH_SUCCESS: return { ... state, isError: false, isLoading: false, data: action.payload } case fetchType.FETCH_SUCCESS: return { ... state, isError: true, isLoading: false } default: return { ... state } } }Copy the code

How does a parent in hooks get a method in a child

  • useImperativeHandle
  • forwardRef
  • -Blair: It’s imperative
{useImperativeHandle - useImperativeHandle - useImperativeHandle; To customize the instance value exposed to the parent component. - imperative - 'notice: '(2) forwardRef -' React. 'create a React component. This component can forward the REF property it accepts to another component under its component tree. - pass the forward ref property to the child component, 'so that the parent component can directly bind to the child component's child or grandson.' - Parameter: a render component - Parameter of the render component: Props and ref import React, {useRef, useImperativeHandle, forwardRef} from 'React '; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; // Parent const App2 = () => {const childRef = useRef(null) const getChildFn = () => {childref.current.go () // } return (<> <div> parent </div> <div onClick={getChildFn} Const Child = const (((props, ref)) => ((props, ref)); Receive props, and ref parameters useImperativeHandle(ref, () => ({// expose method to parent go go: () => {console.log(' props and refs '); Console. log(' Methods in the object returned by the callback of useImperativeHandle are provided for use by the parent component '); }}) return (<div> subcomponent </div>)})Copy the code

Zh-hans.reactjs.org/docs/react-…

Review:

The annotation specification in js

Related @ @ version 16.8.0 @ see https://reactjs.org/docs/hooks-reference.html#usecontext function param {string} address address @ param @returns void @desc description @deprecated Indicates that a function has been deprecated and will be removed completely in a future version of the code. Avoid using this code @date 2014-04-12 @author QETHAN<[email protected]> @Copyright code information @Overview Description of the current code file.Copy the code

www.jsphp.net/js/show-9-2… Segmentfault.com/a/119000000…

review

Write a call

Call () -- first argument: the object to be bound to. If the first argument is null, null, undefined, then the global object is passed in by default. Pass arguments to the function - main functions: - bind the object specified by this in the function - execute the function (pass arguments other than the object bound to this to the function used) - Note: fn can have a return value - Note: fn can have a return value - -eval (string) executes a string as a statement with an argument of a string. - Add a function to an object - execute the function on the object, where this refers to the object - Delete the function property after execution:  useEffect(() => { const obj = { name: 'wu', age: 20 }; function fn (address) { return this.name + this.age + address } Function.prototype._call = function(obj) { if (typeof this ! == 'function') {throw new Error('the _call method must be called with a function object')} const context = obj ? obj : window; // If the argument is null, undefined, or empty, the global object is passed by default, such as window context.fn = this // because this refers to fn const res = context.fn(... Array.from(arguments).slice(1)) // Delete the first argument and return the delete context.fn. Return res} const res = fn._call(obj, 'hangzhou') console.log(res, 'res')}, [])Copy the code

Handwritten apply

The apply - and call methods are roughly the same, binding this, passing arguments other than the bound object to the function, and executing the function. UseEffect (() => {const obj = {name: 'wang', age: 20} function fn (name, age) { return { name: name || this.name, age: age || this.age } } Function.prototype._apply = function(obj) { if (typeof this ! == 'function') {// _call must throw new Error('the _apply method must called with a function object')} const context = obj ? obj : window; context.fn = this const res = context.fn(... [...arguments].slice(1).flat(Infinity)) Delete context.fn return res} const res = fn._apply(obj, 'zhang') console.log(res, 'res')}, [])Copy the code

Write a bind

Bind - bind this to an object in the function body and return a new function - arguments: - First argument: the object to which the method is bound - following arguments: will be passed as arguments to the function - Note: If bind passes two arguments, then the first argument of the returned function is passed to the function as the second argument. - bind this - returns a new function - can pass arguments (bind passes arguments, returns a new function can also pass arguments) - Returns a new function, can also be called by the new command - code: UseEffect (() => {// bind = const obj = {name: 'wang', age: 20}; function fn(address, sex) { return this.name + this.age + address + sex; } Function.prototype._bind = function(obj) { const context = this; / / this point here fn functions (this, pointing to the confirmation of the invocation _bind is for fn calls) const bindParams = Array. The prototype. Slice. The call (the arguments, 1); // Turn an array-like object into a true array. Call is bound to this, Return function() {// _bind returns a new function const resParams = array.prototype.slice (arguments); Return context.apply(obj, bindParams. Concat (bindParams))) Apply}} const newFn = fn.bind(obj, 'chongqing') const res = newFn('man'); Console. log(res, 'res')}, []) When the new function returned by bind is called using the new operator, the this object specified by bind is invalidated because the constructor refers to the instance object. UseEffect (() => {const obj = {name: 'wang', age: 20 } function fn(address, sex) { console.log(this.name, 'this.name') return this.name + this.age + address + sex } Function.prototype._bind = function(obj) { // The _bind method can only be called on function objects if (typeof this! == 'function') {throw new Error('bind must be called on the funciton object')} // Prototype Using intermediate functions to relay, Example of the ParasiticFn function. // examples of the parasiticfn. prototype => fn. // ParasiticFn does not have any attribute or method of ParasiticFn itself // ParasiticFn = function(){}; ParasiticFn.prototype = this.prototype closure.prototype = new ParasiticFn() const bindParams = Array.prototype.slice.call(arguments, 1) const context = this // fn function closure() { const closureParams = Array.prototype.slice.call(arguments) return context.apply(this instanceof ParasiticFn ? this : Obj, bindparams.concat (closureParams)) // 1. This in the closure() function is referred to differently depending on how it is called (note that this is also referred to differently than this outside the closure function) // 2. When invoked with the new command, closure is treated as a constructor, with this pointing to the instance object // 3. // 4. This instanceof ParasiticFn? this : Obj means: // 5. // How to call the new function, } return closure} const newFn = fn._bind(obj, obj) 'chongqign') const resOrdinary = newFn('man') console.log(resOrdinary, 'resOrdinary') // wang this.name // wang20chongqignman resOrdinary const resConstructor = new newFn('woman') console.log(resConstructor, 'resConstructor') // undefined "this.name" // {} })Copy the code

Github.com/mqyqingfeng…

Logical operator

&&

- If the Boolean value of the first operator is true => return the value of the second operator. - If the Boolean value of the first operator is false => Return the value of the first operator without short-circuiting the evaluation of the second operator. - An operation that skips the second operator is called short-circuiting multiple: Return the value summary of the first expression that is false: False && 2 => false // If false => false Return the value of an expression whose Boolean is false false "&& 2 =>" // execute until the first expression is false and the Boolean is false, no longer execute, Return the value of the current expression "true && 1 && [] && 0 && {} => 0 // If the Boolean value is false at 0, the current value is 0Copy the code

&&

The && operation rule - returns the value of the first expression if the Boolean value of the first operator is true and no further operators are evaluated - returns the value of the second operator if the Boolean value of the first operator is false (if there are only two operators)Copy the code