繁体   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