简体   繁体   English

React class 组件是否有等效于 UseMemo 或 UseCallback 的组件?

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

As the title says, how can I reproduce useMemo or useCallback with React class component?正如标题所说,如何使用 React class 组件重现 useMemo 或 useCallback? I am doing some heavy calculation and I don't want the component to recalculate the value every time it's rendered again.我正在做一些繁重的计算,我不希望组件在每次再次呈现时都重新计算值。 Is the only solution to convert my class component to a function component?将我的 class 组件转换为 function 组件的唯一解决方案是什么?

useMemo - You can store the memoized version directly on the instance, along with any information that you want to use to invalidate and recalculate that information. useMemo - 您可以将备忘版本直接存储在实例上,以及您想要用来使该信息无效和重新计算的任何信息。 See What about memoization?请参阅记忆化怎么样? in the React You Probably Don't Need Derived State article.在 React You Probably Don't Need Derived State文章中。

useCallback - You typically don't need to create callbacks when using a class component, you make them methods of the class (perhaps bind ing them in the constructor) or assign arrow functions to properties in the constructor, so the need for useCallback doesn't arise. useCallback - 在使用 class 组件时,您通常不需要创建回调,您可以将它们设为 class 的方法(可能在构造函数中bind它们)或将箭头函数分配给构造函数中的属性,因此不需要useCallback出现。 Those methods can use this.state , this.setState , and when setting new state based on existing state, the callback form of this.setState .这些方法可以使用this.statethis.setState ,以及在现有 state 的基础上设置新的this.setState时, this.setState 的回调形式。 useCallback is more helpful in function components because typically the callbacks are created within the function, and you don't want to use a new copy on every render. useCallback在 function 组件中更有用,因为通常回调是在 function 中创建的,并且您不想在每次渲染时都使用新副本。

Here's an example using a very quick-and-dirty memoization helper (you may want a library instead, as described in the article linked above).这是一个使用非常快速和简单的记忆助手的示例(您可能需要一个库,如上面链接的文章中所述)。 Notice how derivedValue is only updated when value1 or value2 change, not when value3 changes.请注意derivedValue如何仅在value1value2更改时更新,而不是在value3更改时更新。 Also note that the click handler is stable (doesn't change on each render), so we only see Button render once.另请注意,点击处理程序是稳定的(不会在每次渲染时更改),因此我们只看到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 doesn't come with a built in way to do memoization for class components, but you can use an external memoization library, or create your own if you want. React 没有内置的方法来对 class 组件进行记忆,但是您可以使用外部记忆库,或者如果需要,可以创建自己的记忆库。 For example, using memoize-one :例如,使用memoize-one

import memoizeOne from 'memoize-one';

class Example extends React.Component {

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

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

    // ...
  }
}

how can I reproduce [...] useCallback我怎样才能重现[...] useCallback

Callbacks don't usually need to be memoized in class components.回调通常不需要在 class 组件中记忆。 If your callback is simply a method on the class, it will automatically be a stable reference between renders.如果您的回调只是 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