hooks组件详解(上)
  1. useState用法
  2. useREducer用法
  3. useContent用法
  4. useEffect & useLayoutEffect的区别用法
  5. useMemo && React.memo && useCallback用法

1.useState用法

  • useState使用状态
  • 注意事项
    • 不可以局部更新
      • 如果state是一个对象,setState不会自动合并属性
    • 如果setState(obj)如果地址不变,react就会认为数据没变
    • useState可以接收函数
    const [state,setState] = useState(()=>{
       return {}
  })

案例

    function App() {
       const [user,setUser] = useState({name:'小明', age: 18})
       const onClick = ()=>{
           setUser({
           ...user,
           name: '小红'
          })
      }
       return (
           <div className="App">
           <h1>{user.name}</h1>
           <h2>{user.age}</h2>
           <button onClick={onClick}>Click</button>
           </div>
      );
  }

2. useREducer用法

  • 可以理解成useState的复杂版
    const initial = {
       n: 0
  };

   const reducer = (state, action) => {
       if (action.type === "add") {
           return { n: state.n + action.number };
      } else if (action.type === "multi") {
           return { n: state.n * 2 };
      } else {
           throw new Error("unknown type");
      }
  };

   function App() {
       const [state, dispatch] = useReducer(reducer, initial);
       const { n } = state;
       const onClick = () => {
           dispatch({ type: "add", number: 1 });
      };
       const onClick2 = () => {
           dispatch({ type: "add", number: 2 });
      };
       return (
           <div className="App">
           <h1>n: {n}</h1>

           <button onClick={onClick}>+1</button>
           <button onClick={onClick2}>+2</button>
           </div>
      );
  }

3. useContent用法

  • useContent全局变量是全局的上下文
  • 注意
    • 不是响应式的
      • 在一个模块将C里面的值改变后,另一个模块不会感知这个变化
    const C = createContext(null);

   function App() {
       console.log("App 执行了");
       const [n, setN] = useState(0);
       return (
           <C.Provider value={{ n, setN }}>
           <div className="App">
               <Baba />
           </div>
           </C.Provider>
      );
  }

   function Baba() {
       const { n, setN } = useContext(C);
       return (
           <div>
           我是爸爸 n: {n} <Child />
           </div>
      );
  }

   function Child() {
       const { n, setN } = useContext(C);
       const onClick = () => {
           setN(i => i + 1);
      };
       return (
           <div>
           我是儿子 我得到的 n: {n}
           <button onClick={onClick}>+1</button>
           </div>
      );
  }

4. useEffect & useLayoutEffect的区别用法

  • useEffect 副作用
    • 对环境的改变就是副作用,如修改了document.title
  • 用途
    • 在函数组件中模拟componentDidMount\componentDidUpdate\componentWillUnmount
    • 以上三种用途可以同时存在
  • 当多个useEffect出现时,会按照出现的次序执行
    function App(){
       const [n,setN] = useState(0)
       const add = ()=>{
           setN((state)=>{return state+1})
      }
       useEffect(()=>{
           console.log("第一次渲染执行")
      },[])
       useEffect(()=>{
           console.log("n发生变化是执行")
      },[n])
       useEffect(()=>{
           return ()=>{
               console.log("页面销毁时执行")
          }
      },[])
       return(
           <div>
              {n}
               <button onClick={add}>add</button>
           </div>
      )
  }

useLayoutEffect

用法和useEffect完全相同 案例一

    const App = () => {
       const [value, setValue] = useState(0);

       useEffect(() => {
           document.querySelector("#x").innerText = `value: 1000`;
      }, [value]);

       return (
           <div id="x" onClick={() => setValue(0)}>
               value: {value}
           </div>
      );
  };

上面的代码会在会浏览器开始显示value:0,然后在显示value:100;(如果想让浏览器直接显示value:100)

    useLayoutEffect(() => {
       document.querySelector("#x").innerText = `value: 1000`;
  }, [value]);

useEffect和useLayoutEffect的区别

  • useEffect在render之后执行,所以页面会先显示value:0然后在更新为value:1000
  • useLayoutEffects在render之前执行,在页面渲染之前value已经被更改为1000; 固两者这的区别就是执行时机的区别,在开发过程中推荐使用useEffect

5. useMemo && React.memo && useCallback用法

  • useMemo为了解决React的多余渲染
    • 场景 当App组件引用子组件时,当App组件更新时会重新调用App()重新并重新渲染子组件,这就导致了子组件在没有任何改变就被重新渲染了.
  • useMemo 搭配React.memo使用
    function App(){
   console.log("调用了app")
   const [n,setN] = useState(0)
   const [m,setM] = useState(0)
   const addN = ()=>{
       setN((state)=>{
           return state+1
      })
  }
   const addM = useMemo(()=>{
       return ()=>{
                   setM((state)=>{
                       return state+1
                  })
              }
  },[m])
   return (
       <div>
           <div>
               prend:{n}
               <button onClick={addN}>addN</button>
           </div>
          {/*<Child2 data={m} onClick={addM}></Child2>*/}
           <Child2 data={m} onClick={addM}></Child2>
       </div>
  )

}

const Child2 = React.memo((props)=>{
   console.log("调用了CHild")
   return(
       <div>
           Child: {props.data}
           <button onClick={props.onClick}>addM</button>
       </div>
  )
})

usememo的语法糖 useCallback

    //useMemo的语法糖
    const addM =useCallback(
        ()=>{
            setM((state)=>{
                return state+1
            })
        },[m]
    )
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇