亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React?中的重新渲染類組件及函數組件

 更新時間:2022年11月22日 11:00:00   作者:阿里巴巴終端技術  
這篇文章主要為大家介紹了React?中的重新渲染類組件及函數組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

緣起

React 重新渲染,指的是在類函數中,會重新執(zhí)行 render 函數,類似 Flutter 中的 build 函數,函數組件中,會重新執(zhí)行這個函數

React 組件在組件的狀態(tài) state 或者組件的屬性 props 改變的時候,會重新渲染,條件簡單,但是實際上稍不注意,會引起災難性的重新渲染

類組件

為什么拿類組件先說,怎么說呢,更好理解?還有前幾年比較流行的一些常見面試題

React 中的 setState 什么時候是同步的,什么時候是異步的

React setState 怎么獲取最新的 state

以下代碼的輸出值是什么,頁面展示是怎么變化的

  test = () => {
    // s1 = 1
    const { s1 } = this.state;
    this.setState({ s1: s1 + 1});
    this.setState({ s1: s1 + 1});
    this.setState({ s1: s1 + 1});
    console.log(s1)
  };
  render() {
    return (
      <div>
        <button onClick={this.test}>按鈕</button>
        <div>{this.state.s1}</div>
      </div>
    );
  }

看到這些類型的面試問題,熟悉 React 事務機制的你一定能答出來,畢竟不難嘛,哈?你不知道 React 的事務機制?百度|谷歌|360|搜狗|必應 React 事務機制

React 合成事件

React 組件觸發(fā)的事件會被冒泡到 document(在 react v17 中是 react 掛載的節(jié)點,例如 document.querySelector('#app')),然后 React 按照觸發(fā)路徑上收集事件回調,分發(fā)事件。

  • 這里是不是突發(fā)奇想,如果禁用了,在觸發(fā)事件的節(jié)點,通過原生事件禁止事件冒泡,是不是 React 事件就沒法觸發(fā)了?確實是這樣,沒法冒泡了,React 都沒法收集事件和分發(fā)事件了,注意這個冒泡不是 React 合成事件的冒泡。
  • 發(fā)散一下還能想到的另外一個點,React ,就算是在合成捕獲階段觸發(fā)的事件,依舊在原生冒泡事件觸發(fā)之后
reactEventCallback = () => {
  // s1 s2 s3 都是 1
  const { s1, s2, s3 } = this.state;
  this.setState({ s1: s1 + 1 });
  this.setState({ s2: s2 + 1 });
  this.setState({ s3: s3 + 1 });
  console.log('after setState s1:', this.state.s1);
  // 這里依舊輸出 1, 頁面展示 2,頁面僅重新渲染一次
};
<button
  onClick={this.reactEventCallback}
  onClickCapture={this.reactEventCallbackCapture}
>
  React Event
</button>
<div>
  S1: {s1} S2: {s2} S3: {s3}
</div>

定時器回調后觸發(fā) setState

定時器回調執(zhí)行 setState 是同步的,可以在執(zhí)行 setState 之后直接獲取,最新的值,例如下面代碼

timerCallback = () => {
  setTimeout(() => {
    // s1 s2 s3 都是 1
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1 });
    console.log('after setState s1:', this.state.s1);
    // 輸出 2 頁面渲染 3 次
    this.setState({ s2: s2 + 1 });
    this.setState({ s3: s3 + 1 });
  });
};

異步函數后調觸發(fā) setState

異步函數回調執(zhí)行 setState 是同步的,可以在執(zhí)行 setState 之后直接獲取,最新的值,例如下面代碼

asyncCallback = () => {
  Promise.resolve().then(() => {
    // s1 s2 s3 都是 1
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1 });
    console.log('after setState s1:', this.state.s1);
    // 輸出 2 頁面渲染 3 次
    this.setState({ s2: s2 + 1 });
    this.setState({ s3: s3 + 1 });
  });
};

原生事件觸發(fā)

原生事件同樣不受 React 事務機制影響,所以 setState 表現(xiàn)也是同步的

componentDidMount() {
  const btn1 = document.getElementById('native-event');
  btn1?.addEventListener('click', this.nativeCallback);
}
nativeCallback = () => {
  // s1 s2 s3 都是 1
  const { s1, s2, s3 } = this.state;
  this.setState({ s1: s1 + 1 });
  console.log('after setState s1:', this.state.s1);
  // 輸出 2 頁面渲染 3 次
  this.setState({ s2: s2 + 1 });
  this.setState({ s3: s3 + 1 });
};
<button id="native-event">Native Event</button>

setState 修改不參與渲染的屬性

setState 調用就會引起就會組件重新渲染,即使這個狀態(tài)沒有參與頁面渲染,所以,請不要把非渲染屬性放 state 里面,即使放了 state,也請不要通過 setState 去修改這個狀態(tài),直接調用 this.state.xxx = xxx 就好,這種不參與渲染的屬性,直接掛在 this 上就好,參考下圖

// s1 s2 s3 為渲染的屬性,s4 非渲染屬性
state = {
  s1: 1,
  s2: 1,
  s3: 1,
  s4: 1,
};
s5 = 1;
changeNotUsedState = () => {
  const { s4 } = this.state;
  this.setState({ s4: s4 + 1 });
  // 頁面會重新渲染
  // 頁面不會重新渲染
  this.state.s4 = 2;
  this.s5 = 2;
};
<div>
  S1: {s1} S2: {s2} S3: {s3}
</div>;

只是調用 setState,頁面會不會重新渲染

幾種情況,分別是:

  • 直接調用 setState,無參數
  • setState,新 state 和老 state 完全一致,也就是同樣的 state
sameState = () => {
  const { s1 } = this.state;
  this.setState({ s1 });
  // 頁面會重新渲染
};
noParams = () => {
  this.setState({});
  // 頁面會重新渲染
};

這兩種情況,處理起來和普通的修改狀態(tài)的 setState 一致,都會引起重新渲染的

多次渲染的問題

為什么要提上面這些,仔細看,這里提到了很多次渲染的 3 次,比較契合我們日常寫代碼的,異步函數回調,畢竟在定時器回調或者給組件綁定原生事件(沒事找事是吧?),挺少這么做的吧,但是異步回調就很多了,比如網絡請求啥的,改變個 state 還是挺常見的,但是渲染多次,就是不行!不過利用 setState 實際上是傳一個新對象合并機制,可以把變化的屬性合并在新的對象里面,一次性提交全部變更,就不用調用多次 setState

asyncCallbackMerge = () => {
  Promise.resolve().then(() => {
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
    console.log('after setState s1:', this.state.s1);
    // 輸出 2 頁面渲染1次
  });
};

這樣就可以在非 React 的事務流中避開多次渲染的問題

測試代碼

import React from 'react';
interface State {
  s1: number;
  s2: number;
  s3: number;
  s4: number;
}
// eslint-disable-next-line @iceworks/best-practices/recommend-functional-component
export default class TestClass extends React.Component<any, State> {
  renderTime: number;
  constructor(props: any) {
    super(props);
    this.renderTime = 0;
    this.state = {
      s1: 1,
      s2: 1,
      s3: 1,
      s4: 1,
    };
  }
  componentDidMount() {
    const btn1 = document.getElementById('native-event');
    const btn2 = document.getElementById('native-event-async');
    btn1?.addEventListener('click', this.nativeCallback);
    btn2?.addEventListener('click', this.nativeCallbackMerge);
  }
  changeNotUsedState = () => {
    const { s4 } = this.state;
    this.setState({ s4: s4 + 1 });
  };
  reactEventCallback = () => {
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1 });
    this.setState({ s2: s2 + 1 });
    this.setState({ s3: s3 + 1 });
    console.log('after setState s1:', this.state.s1);
  };
  timerCallback = () => {
    setTimeout(() => {
      const { s1, s2, s3 } = this.state;
      this.setState({ s1: s1 + 1 });
      console.log('after setState s1:', this.state.s1);
      this.setState({ s2: s2 + 1 });
      this.setState({ s3: s3 + 1 });
    });
  };
  asyncCallback = () => {
    Promise.resolve().then(() => {
      const { s1, s2, s3 } = this.state;
      this.setState({ s1: s1 + 1 });
      console.log('after setState s1:', this.state.s1);
      this.setState({ s2: s2 + 1 });
      this.setState({ s3: s3 + 1 });
    });
  };
  nativeCallback = () => {
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1 });
    console.log('after setState s1:', this.state.s1);
    this.setState({ s2: s2 + 1 });
    this.setState({ s3: s3 + 1 });
  };
  timerCallbackMerge = () => {
    setTimeout(() => {
      const { s1, s2, s3 } = this.state;
      this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
      console.log('after setState s1:', this.state.s1);
    });
  };
  asyncCallbackMerge = () => {
    Promise.resolve().then(() => {
      const { s1, s2, s3 } = this.state;
      this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
      console.log('after setState s1:', this.state.s1);
    });
  };
  nativeCallbackMerge = () => {
    const { s1, s2, s3 } = this.state;
    this.setState({ s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 });
    console.log('after setState s1:', this.state.s1);
  };
  sameState = () => {
    const { s1, s2, s3 } = this.state;
    this.setState({ s1 });
    this.setState({ s2 });
    this.setState({ s3 });
    console.log('after setState s1:', this.state.s1);
  };
  withoutParams = () => {
    this.setState({});
  };
  render() {
    console.log('renderTime', ++this.renderTime);
    const { s1, s2, s3 } = this.state;
    return (
      <div className="test">
        <button onClick={this.reactEventCallback}>React Event</button>
        <button onClick={this.timerCallback}>Timer Callback</button>
        <button onClick={this.asyncCallback}>Async Callback</button>
        <button id="native-event">Native Event</button>
        <button onClick={this.timerCallbackMerge}>Timer Callback Merge</button>
        <button onClick={this.asyncCallbackMerge}>Async Callback Merge</button>
        <button id="native-event-async">Native Event Merge</button>
        <button onClick={this.changeNotUsedState}>Change Not Used State</button>
        <button onClick={this.sameState}>React Event Set Same State</button>
        <button onClick={this.withoutParams}>
          React Event SetState Without Params
        </button>
        <div>
          S1: {s1} S2: {s2} S3: {s3}
        </div>
      </div>
    );
  }
}

函數組件

函數組件重新渲染的條件也和類組件一樣,組件的屬性 Props 和組件的狀態(tài) State 有修改的時候,會觸發(fā)組件重新渲染,所以類組件存在的問題,函數組件同樣也存在,而且因為函數組件的 state 不是一個對象,情況就更糟糕

React 合成事件

const reactEventCallback = () => {
  // S1 S2 S3 都是 1
  setS1((i) => i + 1);
  setS2((i) => i + 1);
  setS3((i) => i + 1);
  // 頁面只會渲染一次, S1 S2 S3 都是 2
};

定時器回調

const timerCallback = () => {
  setTimeout(() => {
    // S1 S2 S3 都是 1
    setS1((i) => i + 1);
    setS2((i) => i + 1);
    setS3((i) => i + 1);
    // 頁面只會渲染三次, S1 S2 S3 都是 2
  });
};

異步函數回調

const asyncCallback = () => {
  Promise.resolve().then(() => {
    // S1 S2 S3 都是 1
    setS1((i) => i + 1);
    setS2((i) => i + 1);
    setS3((i) => i + 1);
    // 頁面只會渲染三次, S1 S2 S3 都是 2
  });
};

原生事件

useEffect(() => {
  const handler = () => {
    // S1 S2 S3 都是 1
    setS1((i) => i + 1);
    setS2((i) => i + 1);
    setS3((i) => i + 1);
    // 頁面只會渲染三次, S1 S2 S3 都是 2
  };
  containerRef.current?.addEventListener('click', handler);
  return () => containerRef.current?.removeEventListener('click', handler);
}, []);

更新沒使用的狀態(tài)

const [s4, setS4] = useState<number>(1);
const unuseState = () => {
  setS4((s) => s + 1);
  // s4 === 2 頁面渲染一次 S4 頁面上沒用到
};

小結

以上的全部情況,在 React Hook 中表現(xiàn)的情況和類組件表現(xiàn)完全一致,沒有任何差別,但是也有表現(xiàn)不一致的地方

不同的情況 設置同樣的 State

React Hook 中設置同樣的 State,并不會引起重新渲染,這點和類組件不一樣,但是這個不一定的,引用 React 官方文檔說法

如果你更新 State Hook 后的 state 與當前的 state 相同時,React 將跳過子組件的渲染并且不會觸發(fā) effect 的執(zhí)行。(React 使用 Object.is 比較算法 來比較 state。)

需要注意的是,React 可能仍需要在跳過渲染前渲染該組件。不過由于 React 不會對組件樹的“深層”節(jié)點進行不必要的渲染,所以大可不必擔心。如果你在渲染期間執(zhí)行了高開銷的計算,則可以使用 useMemo 來進行優(yōu)化。

官方穩(wěn)定有提到,新舊 State 淺比較完全一致是不會重新渲染的,但是有可能還是會導致重新渲染

// React Hook
const sameState = () => {
  setS1((i) => i);
  setS2((i) => i);
  setS3((i) => i);
  console.log(renderTimeRef.current);
  // 頁面并不會重新渲染
};
// 類組件中
sameState = () => {
  const { s1, s2, s3 } = this.state;
  this.setState({ s1 });
  this.setState({ s2 });
  this.setState({ s3 });
  console.log('after setState s1:', this.state.s1);
  // 頁面會重新渲染
};

這個特性存在,有些時候想要獲取最新的 state,又不想給某個函數添加 state 依賴或者給 state 添加一個 useRef,可以通過這個函數去或者這個 state 的最新值

const sameState = () => {
  setS1((i) => {
    const latestS1 = i;
    // latestS1 是當前 S1 最新的值,可以在這里處理一些和 S1 相關的邏輯
    return latestS1;
  });
};

React Hook 中避免多次渲染

React Hookstate 并不是一個對象,所以不會自動合并更新對象,那怎么解決這個異步函數之后多次 setState 重新渲染的問題?

將全部 state 合并成一個對象

const [state, setState] = useState({ s1: 1, s2: 1, s3: 1 });
setState((prevState) => {
  setTimeout(() => {
    const { s1, s2, s3 } = prevState;
    return { ...prevState, s1: s1 + 1, s2: s2 + 1, s3: s3 + 1 };
  });
});

參考類的的 this.state 是個對象的方法,把全部的 state 合并在一個組件里面,然后需要更新某個屬性的時候,直接調用 setState 即可,和類組件的操作完全一致,這是一種方案

使用 useReducer

雖然這個 hook 的存在感確實低,但是多狀態(tài)的組件用這個來替代 useState 確實不錯

const initialState = { s1: 1, s2: 1, s3: 1 };
function reducer(state, action) {
  switch (action.type) {
    case 'update':
      return { s1: state.s1 + 1, s2: state.s2 + 1, s3: state.s3 + 1 };
    default:
      return state;
  }
}
const [reducerState, dispatch] = useReducer(reducer, initialState);
const reducerDispatch = () => {
  setTimeout(() => {
    dispatch({ type: 'update' });
  });
};

具體的用法不展開了,用起來和 redux 差別不大

狀態(tài)直接用 Ref 聲明,需要更新的時候調用更新的函數(不推薦)

// S4 不參與渲染
const [s4, setS4] = useState<number>(1);
// update 就是 useReducer 的 dispatch,調用就更更新頁面,比定義一個不渲染的 state 好多了
const [, update] = useReducer((c) => c + 1, 0);
const state1Ref = useRef(1);
const state2Ref = useRef(1);
const unRefSetState = () => {
  // 優(yōu)先更新 ref 的值
  state1Ref.current += 1;
  state2Ref.current += 1;
  setS4((i) => i + 1);
};
const unRefSetState = () => {
  // 優(yōu)先更新 ref 的值
  state1Ref.current += 1;
  state2Ref.current += 1;
  update();
};
<div>
  state1Ref: {state1Ref.current} state2Ref: {state2Ref.current}
</div>;

這樣做,把真正渲染的 state 放到了 ref 里面,這樣有個好處,就是函數里面不用聲明這個 state 的依賴了,但是壞處非常多,更新的時候必須說動調用 update,同時把 ref 用來渲染也比較奇怪

自定義 Hook

自定義 Hook 如果在組件中使用,任何自定義 Hook 中的狀態(tài)改變,都會引起組件重新渲染,包括組件中沒用到的,但是定義在自定義 Hook 中的狀態(tài)

簡單的例子,下面的自定義 hook,有 iddata 兩個狀態(tài), id 甚至都沒有導出,但是 id 改變的時候,還是會導致引用這個 Hook 的組件重新渲染

// 一個簡單的自定義 Hook,用來請求數據
const useDate = () => {
  const [id, setid] = useState<number>(0);
  const [data, setData] = useState<any>(null);
  useEffect(() => {
    fetch('請求數據的 URL')
      .then((r) => r.json())
      .then((r) => {
        // 組件重新渲染
        setid((i) => i + 1);
        // 組件再次重新渲染
        setData(r);
      });
  }, []);
  return data;
};
// 在組件中使用,即使只導出了 data,但是 id 變化,同時也會導致組件重新渲染,所以組件在獲取到數據的時候,組件會重新渲染兩次
const data = useDate();

測試代碼

// use-data.ts
const useDate = () => {
  const [id, setid] = useState<number>(0);
  const [data, setData] = useState<any>(null);
  useEffect(() => {
    fetch('數據請求地址')
      .then((r) => r.json())
      .then((r) => {
        setid((i) => i + 1);
        setData(r);
      });
  }, []);
  return data;
};
import { useEffect, useReducer, useRef, useState } from 'react';
import useDate from './use-data';
const initialState = { s1: 1, s2: 1, s3: 1 };
function reducer(state, action) {
  switch (action.type) {
    case 'update':
      return { s1: state.s1 + 1, s2: state.s2 + 1, s3: state.s3 + 1 };
    default:
      return state;
  }
}
const TestHook = () => {
  const renderTimeRef = useRef<number>(0);
  const [s1, setS1] = useState<number>(1);
  const [s2, setS2] = useState<number>(1);
  const [s3, setS3] = useState<number>(1);
  const [s4, setS4] = useState<number>(1);
  const [, update] = useReducer((c) => c + 1, 0);
  const state1Ref = useRef(1);
  const state2Ref = useRef(1);
  const data = useDate();
  const [state, setState] = useState({ s1: 1, s2: 1, s3: 1 });
  const [reducerState, dispatch] = useReducer(reducer, initialState);
  const containerRef = useRef<HTMLButtonElement>(null);
  const reactEventCallback = () => {
    setS1((i) => i + 1);
    setS2((i) => i + 1);
    setS3((i) => i + 1);
  };
  const timerCallback = () => {
    setTimeout(() => {
      setS1((i) => i + 1);
      setS2((i) => i + 1);
      setS3((i) => i + 1);
    });
  };
  const asyncCallback = () => {
    Promise.resolve().then(() => {
      setS1((i) => i + 1);
      setS2((i) => i + 1);
      setS3((i) => i + 1);
    });
  };
  const unuseState = () => {
    setS4((i) => i + 1);
  };
  const unRefSetState = () => {
    state1Ref.current += 1;
    state2Ref.current += 1;
    setS4((i) => i + 1);
  };
  const unRefReducer = () => {
    state1Ref.current += 1;
    state2Ref.current += 1;
    update();
  };
  const sameState = () => {
    setS1((i) => i);
    setS2((i) => i);
    setS3((i) => i);
    console.log(renderTimeRef.current);
  };
  const mergeObjectSetState = () => {
    setTimeout(() => {
      setState((prevState) => {
        const { s1: prevS1, s2: prevS2, s3: prevS3 } = prevState;
        return { ...prevState, s1: prevS1 + 1, s2: prevS2 + 1, s3: prevS3 + 1 };
      });
    });
  };
  const reducerDispatch = () => {
    setTimeout(() => {
      dispatch({ type: 'update' });
    });
  };
  useEffect(() => {
    const handler = () => {
      setS1((i) => i + 1);
      setS2((i) => i + 1);
      setS3((i) => i + 1);
    };
    containerRef.current?.addEventListener('click', handler);
    return () => containerRef.current?.removeEventListener('click', handler);
  }, []);
  console.log('render Time Hook', ++renderTimeRef.current);
  console.log('data', data);
  return (
    <div className="test">
      <button onClick={reactEventCallback}>React Event</button>
      <button onClick={timerCallback}>Timer Callback</button>
      <button onClick={asyncCallback}>Async Callback</button>
      <button id="native-event" ref={containerRef}>
        Native Event
      </button>
      <button onClick={unuseState}>Unuse State</button>
      <button onClick={sameState}>Same State</button>
      <button onClick={mergeObjectSetState}>Merge State Into an Object</button>
      <button onClick={reducerDispatch}>Reducer Dispatch</button>
      <button onClick={unRefSetState}>useRef As State With useState</button>
      <button onClick={unRefSetState}>useRef As State With useReducer</button>
      <div>
        S1: {s1} S2: {s2} S3: {s3}
      </div>
      <div>
        Merge Object S1: {state.s1} S2: {state.s2} S3: {state.s3}
      </div>
      <div>
        reducerState Object S1: {reducerState.s1} S2: {reducerState.s2} S3:{' '}
        {reducerState.s3}
      </div>
      <div>
        state1Ref: {state1Ref.current} state2Ref: {state2Ref.current}
      </div>
    </div>
  );
};
export default TestHook;

規(guī)則記不住怎么辦?

上面羅列了一大堆情況,但是這些規(guī)則難免會記不住,React 事務機制導致的兩種完全截然不然的重新渲染機制,確實讓人覺得有點惡心,React 官方也注意到了,既然在事務流的中 setState 可以合并,那不在 React 事務流的回調,能不能也合并,答案是可以的,React 官方其實在 React V18 中, setState 能做到合并,即使在異步回調或者定時器回調或者原生事件綁定中,可以把測試代碼直接丟 React V18 的環(huán)境中嘗試,就算是上面列出的會多次渲染的場景,也不會重新渲染多次

具體可以看下這個地址

Automatic batching for fewer renders in React 18

但是,有了 React V18 最好也記錄一下以上的規(guī)則,對于減少渲染次數還是很有幫助的

以上就是React 中的重新渲染類組件及函數組件的詳細內容,更多關于React 重新渲染組件的資料請關注腳本之家其它相關文章!

相關文章

  • React實現(xiàn)浮層組件的思路與方法詳解

    React實現(xiàn)浮層組件的思路與方法詳解

    React?浮層組件(也稱為彈出組件或彈窗組件)通常是指在用戶界面上浮動顯示的組件,本文主要介紹了浮層組件的實現(xiàn)方法,感興趣的小伙伴可以了解下
    2024-02-02
  • React中useRef的具體使用

    React中useRef的具體使用

    這篇文章主要介紹了React中useRef的具體使用,它可以用來獲取組件實例對象或者是DOM對象,除此之外還有哪些用法,就一起來了解一下
    2021-04-04
  • react-native中路由頁面的跳轉與傳參的實例詳解

    react-native中路由頁面的跳轉與傳參的實例詳解

    這篇文章主要介紹了react-native中路由頁面的跳轉與傳參,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • 你知道怎么基于?React?封裝一個組件嗎

    你知道怎么基于?React?封裝一個組件嗎

    這篇文章主要為大家詳細介紹了React如何封裝一個組件,使用antd的divider組件來講解,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 詳解react如何實現(xiàn)復合組件

    詳解react如何實現(xiàn)復合組件

    在一些react項目開發(fā)中,常常會出現(xiàn)一些組合的情況出現(xiàn),這篇文章主要為大家介紹了復合組件的具體實現(xiàn),感興趣的小伙伴可以跟隨小編一起學習一下
    2024-10-10
  • 解決React報錯Rendered more hooks than during the previous render

    解決React報錯Rendered more hooks than during

    這篇文章主要為大家介紹了React報錯Rendered more hooks than during the previous render解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 詳解React中合并單元格的正確寫法

    詳解React中合并單元格的正確寫法

    用表格進行頁面布局,頁面布局在各種瀏覽器的的兼容性, 本文主要介紹了詳解React中合并單元格的正確寫法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 在?React?中如何從狀態(tài)數組中刪除一個元素

    在?React?中如何從狀態(tài)數組中刪除一個元素

    這篇文章主要介紹了在?React?中從狀態(tài)數組中刪除一個元素,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 詳解在React里使用

    詳解在React里使用"Vuex"

    本篇文章主要介紹了詳解在React里使用"Vuex",小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • React Draggable插件如何實現(xiàn)拖拽功能

    React Draggable插件如何實現(xiàn)拖拽功能

    這篇文章主要介紹了React Draggable插件如何實現(xiàn)拖拽功能問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評論