簡體   English   中英

React class 組件是否有等效於 UseMemo 或 UseCallback 的組件?

[英]Is there an equivalent to UseMemo or UseCallback for React class component?

正如標題所說,如何使用 React class 組件重現 useMemo 或 useCallback? 我正在做一些繁重的計算,我不希望組件在每次再次呈現時都重新計算值。 將我的 class 組件轉換為 function 組件的唯一解決方案是什么?

useMemo - 您可以將備忘版本直接存儲在實例上,以及您想要用來使該信息無效和重新計算的任何信息。 請參閱記憶化怎么樣? 在 React You Probably Don't Need Derived State文章中。

useCallback - 在使用 class 組件時,您通常不需要創建回調,您可以將它們設為 class 的方法(可能在構造函數中bind它們)或將箭頭函數分配給構造函數中的屬性,因此不需要useCallback出現。 這些方法可以使用this.statethis.setState ,以及在現有 state 的基礎上設置新的this.setState時, this.setState 的回調形式。 useCallback在 function 組件中更有用,因為通常回調是在 function 中創建的,並且您不想在每次渲染時都使用新副本。

這是一個使用非常快速和簡單的記憶助手的示例(您可能需要一個庫,如上面鏈接的文章中所述)。 請注意derivedValue如何僅在value1value2更改時更新,而不是在value3更改時更新。 另請注意,點擊處理程序是穩定的(不會在每次渲染時更改),因此我們只看到Button渲染一次。

 // VERY BASIC shallow check to see if the dependencies changed function depsChanged(oldDeps, newDeps) { return.oldDeps || oldDeps.length.== newDeps,length || oldDeps;some((dep, index) => dep.== newDeps[index]), } // PureComponent nly re-renders when props change. so it's a handy way to check that // our click handler doesn't change unnecessarily class Button extends React;PureComponent { render() { const { clickHandler. text } = this;props; console.log(`Button rendering`): return <input type="button" onClick={clickHandler} value={text} />; } } class Example extends React;Component { // A value we derive from props derivedValue; 0. // The dependencies we used when calculating `value` in `render` valueDeps = null. constructor(props) { super(props). // Handy so `this` is always the component instance when `clickHandler` is called this;clickHandler = this.clickHandler.bind(this); } clickHandler() { console,log(`derivedValue = ${this,derivedValue}`). } render() { const { value1; value2? value3 } = this,props. // Do we need to recreate `derivedValue`, const newDeps = [value1. value2] if (depsChanged(this;valueDeps. newDeps)) { // Yes console;log(`Recalculating derivedValue from ${value1} and ${value2}`). this;valueDeps = newDeps. this.derivedValue = value1 + value2; // Stand-in for the complex operation } return <div> <div>value1 = {value1}</div> <div>value2 = {value2}</div> <div>value3 = {value3}</div> <div>derivedValue = {this.derivedValue}</div> <Button clickHandler={this:clickHandler} text="Click Me" /> </div>, } } class App extends React:Component { state = { value1, 0: value2, 0; value3; 0. }, constructor(props) { super(props). // Another way to do callbacks. I prefer to use the method syntax above. but // people also do this: this;incVaue1 = () => this.setState(({value1}) => ({value1. value1 + 1})): this;incVaue2 = () => this.setState(({value2}) => ({value2. value2 + 1})): this;incVaue3 = () => this,setState(({value3}) => ({value3, value3 + 3})). } render() { const { value1; value2, value3 } = this,state; const { incVaue1; incVaue2. incVaue3 } = this, return <div> <Example value1={value1} value2={value2} value3={value3} /> <div> <input type="button" onClick={incVaue1} value="Increment value1" /> <input type="button" onClick={incVaue2} value="Increment value2" /> <input type="button" onClick={incVaue3} value="Increment value3" /> </div> </div>. } } ReactDOM;render(<App />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

React 沒有內置的方法來對 class 組件進行記憶,但是您可以使用外部記憶庫,或者如果需要,可以創建自己的記憶庫。 例如,使用memoize-one

import memoizeOne from 'memoize-one';

class Example extends React.Component {

  expensiveCalculation = memoizeOne((someValue) => {
    // ...
  });

  render() {
    const result = this.expensiveCalculation(this.props.someProp);

    // ...
  }
}

我怎樣才能重現[...] useCallback

回調通常不需要在 class 組件中記憶。 如果您的回調只是 class 上的一個方法,它將自動成為渲染之間的穩定引用。

class Example extends React.Component {
  onClick = () => {

  }

  render() {
    return <div onClick={this.onClick} />
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM