首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不使用shouldComponentUpdate的情况下更好地设计我的反应性项目

如何在不使用shouldComponentUpdate的情况下更好地设计我的反应性项目
EN

Stack Overflow用户
提问于 2021-04-01 03:01:43
回答 3查看 146关注 0票数 4

我在试着建造一分钟的烛台。

我有一个组件,它将不断地将一个数字(交易价格)传递给他的子组件。

此子组件将根据从父组件获得的新数字更新其状态:(高、低、打开、关闭)。(例如,如果输入的数字高于当前的this.state.high,它将将this.state.high更新为新的数字),在每分钟执行setInterval函数之后,它将获取状态并构造蜡烛并将其传递给自己的子节点。

国家是:high, low, open, close, newCandle

我用的是

代码语言:javascript
运行
复制
shouldComponentUpdate(nextProps:props, nextState:state){
        
        if(this.props !== nextProps)
          this.updateStates(nextProps.newTradePrice); //will update the high, low, open, close state 
        if(JSON.stringify(nextState.nextMinuteCandle) !== JSON.stringify(this.state.nextMinuteCandle)  ) //once the one minute interval is up, there will be a function that will auto set the newCandle state to a new Candle base on the current high, low, open, close state
          return true;
        return false;
}

我在文档中看到,shouldComponentUpdate只用于优化,而不是阻止reRender。我使用它来防止reRender和无限循环。

我被困在这个上面好几天了,我想不出一个更好的设计方法。对如何更好地设计这个有什么建议吗?

第二个相关问题:

事实上,我几乎所有的组件都依赖shouldComponentUpdate。这不可能是对的例如,我有一个CalculateAverageVolume子组件,它接受this.state.newCandle。并在每次newCandle更改时(即每分钟)更新音量

代码语言:javascript
运行
复制
constructor(props: props) {
  super(props);
  this.state = {
    [...],
    currentAverage: 0,
    showVolume: true
  };
}

onCloseHandler()
{
    this.setState({showVolume: false});
}

updateAvg(newCandleStick: CandleStick){
   //do caluation and use this.setState to update the this.state.currentAverage
}

shouldComponentUpdate(nextProps:props, nextState:state)
{
    if(JSON.stringify(this.props.candleStick) !== JSON.stringify(nextProps.candleStick) || this.state.showVolume !== nextState.showVolume){
        this.updateAvg(nextProps.candleStick);
        return true;
    }
    return false;
}

render() {
    return (
        <>
        {(this.state.showVolume &&
                <IndicatorCard 
                    cardHeader="Volume"
                    currentInfo={this.state.currentAverage.toString()}
                    onCloseHandler={()=>this.onCloseHandler()}>
                </IndicatorCard>
        )}
        </>
    );
}

}

有人能教我如何设计这个或重组这个吗?这是完美的,但似乎不是正确的方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-04-03 04:39:27

我会将组件简化如下。

代码语言:javascript
运行
复制
import { useMemo, useState, memo, useCallback } from "react";

function Component({ candleStick }) {
  // use props here to calculate average
  const updateAverage = () => 0; // use candleStick props to calculate avg here
  const [showVolume, setShowVolume] = useState();
  // Compute the average from prop when component re-renders
  // I would also add useMemo if `updateAverage` is an expensive function
  // so that when prop remains same and `showVolume` changes we don't need to calculate it again
  const currentAverage = useMemo(updateAverage, [candleStick]);
  const onCloseHandler = useCallback(() => setShowVolume(val => !val), []);

  return showVolume ? (
    <IndicatorCard
      cardHeader="Volume"
      currentInfo={currentAverage}
      onCloseHandler={onCloseHandler}
    />
  ) : null;
}

// If true is returned, component won't re-render. 
// Btw React.memo by default would do shallow comparison
// But if deep comparison function is required, I would use lodash or other utility to do the check instead of JSON.stringify.
const arePropsEqual = (prev, next) =>
  isEqual(prev.candleStick, next.candleStick);

export default memo(Component, arePropsEqual);
票数 3
EN

Stack Overflow用户

发布于 2021-04-09 08:22:12

shouldComponentUpdate通常是为您可以控制的离散事件保留的。但是,似乎您正在处理一个连续的数据流。

处理这一问题的两种方法:

  • 将一个函数引用传递给子组件,该引用处理子组件中的流,并让它处理子组件中的状态更新。

参考执行情况:

使用上下文API:https://javascript.plainenglish.io/react-context-api-part-2-updating-state-through-a-consumer-7be723b54d7b

  • 上行状态
票数 1
EN

Stack Overflow用户

发布于 2021-04-09 21:58:01

当我开始反应的时候,我撞到了你所在的那个位置。这里的问题是,这种反应,至少是它的基本方面,在讨论数据流时是不够的。您需要研究的是React数据管理框架,其中Redux可能是最流行的。查看Redux,确保您正在查看基于钩子的最新文档。你会对自己说“哦!这很有道理”-我知道我说了。

其他类似的框架是React查询和React自己的上下文API。我想指出的主要一点是,您确实需要数据管理来完成您想要的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66897874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档