Skip to main content

React

1) 组件

组件是一个UI片段,拥有独立的逻辑和显示


类型: Class组件, 函数组件


2) Hooks

1> useState

    特点:

    - 异步更新

    - 可能会被合并

        setCount(count + 1)

        setCount(count + 1)

        setCount(count + 1)

            最后只会是初始值 + 1

    但是

        setCount(count => count + 1)

        setCount(count => count + 1)

        setCount(count => count + 1)

            会是初始值 + 3

    - 不可变数据


增删改

增: array.concat()

删: array.filter()

改: array.map()


状态提升: 子组件只执行父组件传过来的函数,数据显示。


immer:

    install:

    npm install immer --save

    

    use:

    import produce from 'immer'

    1) setUserInfo(produce(draft => {

        draft.age = xxx;

    }))

    2) setList(produce(draft => {

        draft.push({xxx});

    }))


immutable.js


2> useEffect

useEffect(() => {

    xxx

}, [])


生命周期:创建,更新,销毁

销毁:

useEffect(() => {

    xxx

    return () => {

        xxx //  <= here execute when unmounted

    }

}, [])


React 18开始, useEffect在开发环境下会执行两次

模拟组件 创建,销毁,再创建的完整流程,及早暴露bug

生产环境下执行一次



3> useRef

不用在JSX中显示,最好不用useState,用useRef比较好


1) 用于操作DOM

    const inputRef = useRef<HTMLInputElement>(null);

    function selectInput() {

        const inputElem = inputRef.current;

        if (inputElem) inputElem.select;

    }

    <input ref={inputRef} />

    <button onClick={selectInput}></button>

    


2) 也可传入普通JS变量,但更新不会触发rerender

3) 要和Vue3 ref区分开


4> useMemo

缓存数据,React中常见的性能优化手段

const sum = useMemo(() => {

    return num1 + num2;

}, [num1, num2]);


    受控组件->变化会使variable也变化

<input onChange={e=>setText(e.target.value)} value={text}></input>


5> useCallback

缓存函数,根据依赖来决定是否重新改变

const fn = useCallback(() => {}, [text])


3) 自定义Hook

自定义hook,谁用了这个hook,useEffect就是在谁那里起作用

组件销毁时,一定要解绑DOM事件

e.g. get mouse coordinate

function useMouse() {
const [x, setX] = useState(0);
const [y, setY] = useState(0);

const mouseMoveHandler = (event: MouseEvent) => {
setX(event.clientX);
setY(event.clientY);
};

useEffect(() => {
window.addEventListener("mousemove", mouseMoveHandler);

// un-bundle when destroying component
return () => {
window.removeEventListener("mousemove", mouseMoveHandler);
};
});
return { x, y };
}


4) 第三方Hook

react-use 国外流行

ahooks 国内流行


Hooks使用规则

1) 必须用useXxx来命名

2) 只能在两个地方调用hook: 1) 组件内 2) 另外一个hook内

3) hook不能放在if, else, for里面。每次的执行顺序都必须一致


5) 闭包陷阱

异步函数获取state时,可能不是当前最新的state

可使用useRef来解决

e.g.,

点击alert按钮,然后快速点击 增加 按钮。此时alert展示出来的是最开始的值。

原因: 定时器,把最开始的值存起来了,3秒后才alert出来。

使用Ref:



解释闭包陷阱:

https://juejin.cn/post/6844904193044512782




6) 发布

commands to configure a static server:

    npm run build

    npm install -g serve

    serve -s build


Comments

Popular posts from this blog

Templates

  Template - Polymorphism is the ability of the same code to operate on different types. This ability to operate on multiple types reduces code duplication by allowing the same piece of code to be reused across the different types it can operate on. - Polymorphism comes in a variety of forms. What we are interested in at the moment is parametric polymorphism, meaning that we can write our code so that it is parameterized over what type it operates on.  -That is, we want to declare a type parameter T and replace int with T in the above code. -Then, when we want to call the function, we can specify the type for T and get the function we desire. C++ provides parametric polymorphism through templates. Templated Functions - We can write a templated function by using the keyword template followed by the template parameters in angle brackets (<>). - Unlike function parameters, template parameters may be types, which are specified with typename where the type of the parameter wo...

useMemo的使用场景

 useMemo是用来缓存 计算属性 的。 计算属性是函数的返回值,或者说那些以返回一个值为目标的函数。 有些函数会需要我们手动去点击,有些函数是直接在渲染的时候就执行,在DOM区域被当作属性值一样去使用。后者被称为计算属性。 e.g. const Component = () => { const [ params1 , setParams1 ] = useState ( 0 ); const [ params2 , setParams2 ] = useState ( 0 ); //这种是需要我们手动去调用的函数 const handleFun1 = () => { console . log ( "我需要手动调用,你不点击我不执行" ); setParams1 (( val ) => val + 1 ); }; //这种被称为计算属性,不需要手动调用,在渲染阶段就会执行的。 const computedFun2 = () => { console . log ( "我又执行计算了" ); return params2 ; }; return ( < div onClick = { handleFun1 } > //每次重新渲染的时候我就会执行 computed: { computedFun2 () } </ div > ); }; 上面的代码中,在每次点击div的时候,因为setParams1的缘故,导致params1改变,整个组件都需要重新渲染,也导致comptedFunc2()也需要重新计算。如果computedFunc2的计算量很大,这时候重新计算会比较浪费。 可以使用useMemo: const Com = () => { const [ params1 , setParams1 ] = useState ( 0 ); const [ params2 , setParams2 ] = useState ( 0 ); //这种是需要我们手动去调用的函数 const handleFun1 ...

Valgrind

  Using Valgrind to check memory How to use Valgrind -To valgrind the program, run the valgrind command and give it our program name as an argument. -For example, if we want to run ./myProgram hello 42, we can simply run Valgrind ./myProgram hello 42.  Uninitialized Values -When we run the program, we may use uninitialized values. It needs to be fixed. Valgrind can tell us about the use of uninitialized values. But it only tell when the control flow of the program depends on the unitialized value. For example, uninitialized value appears in the conditional expression of an if, or a loop, or in the switch statement. -If we want to know where the uninitialized value is from, we can use Valgrind    --track-origins=yes ./myProgram -Using -fsanitize=address can find a lot of problems that Memcheck cannot.  -We can use Valgrind with GDB to debug. We can run: --vgdb=full --vgdb-error=0., then Valgrind will stop on the first error that it encounters and give control to ...