【问题标题】:how to prevent re-render while using GraphQL polling如何在使用 GraphQL 轮询时防止重新渲染
【发布时间】:2019-11-25 18:22:02
【问题描述】:

我需要使用轮询来使用 GraphQL 查询数据。但是反应组件应该只在数据发生变化时重新渲染。每次有新数据进入时,如何防止组件重新渲染?以下代码不会阻止重新渲染。

  const Instructions: React.FC<RouteComponentProps<RouteParams>> = props => {
  const [firstTimeDataRender, setFirstTimeDataRender] = useState(true);
  const [instructionData, setInstructionData] = useState<FetchSettlementInstructionsQuery_instructions[]>([]);

  const { data, loading, error } = useQuery<FetchSettlementInstructionsQuery, FetchSettlementInstructionsQueryVariables>(
    settlementInstructionsQuery,
    {
      variables: {
        sort: null,
        filter: { type: SettlementInstructionType.freeOfPayment },
      },
      fetchPolicy: 'cache-and-network',
      pollInterval: 5000,
    },
  );

  if (!!data && firstTimeDataRender) {
    setFirstTimeDataRender(false);
    setInstructionData(data.instructions);
  }

  const showLoading = loading && !(!!data && data.members) && firstTimeDataRender;

  if (data && data.instructions !== instructionData) {
    setInstructionData(data.instructions);
  }

  return (
    <LayoutContent>
      <Instructions data={instructionData} loading={showLoading} error={error ? true : false} />
    </LayoutContent>
  );
};

【问题讨论】:

  • 应该和加载有关。你能显示 组件吗?

标签: reactjs graphql react-apollo


【解决方案1】:

您的重新渲染问题应该与加载有关,或者与数据更改的状态更新有关。
我建议此时从状态中删除数据。 我不确定这段代码是否有效,但已经删除了一些无用的东西。 如果仍然在重新渲染,请尝试在 item 组件级别使用 Memo:

const Memorized = ({ children, rerenderIfThisValueChange = true, orThis = true, id = 0 }) => useMemo(() => children, [rerenderIfThisValueChange, orThis, id]);
<Memorized orThis={instruction.smt} id={instruction.id} >
  <ListItem item={instruction} />
</Memorized>

并使用记忆挂钩返回列表项。

const Instructions: React.FC<RouteComponentProps<RouteParams>> = props => {
      const [firstTimeDataRender, setFirstTimeDataRender] = useState(true);

      const { data, loading, error } = useQuery<FetchSettlementInstructionsQuery, FetchSettlementInstructionsQueryVariables>(
        settlementInstructionsQuery,
        {
          variables: {
            sort: null,
            filter: { type: SettlementInstructionType.freeOfPayment },
          },
          fetchPolicy: 'cache-and-network',
          pollInterval: 5000,
        },
      );

      if (firstTimeDataRender) {
        setFirstTimeDataRender(false);
      }

      const showLoading = loading && !(!!data && data.members) && firstTimeDataRender; //  <= The problem should be here

      const { instructions = [] } = data || {}

      return (
        <LayoutContent>
          <Instructions data={instructions} loading={showLoading} error={!!error} />
        </LayoutContent>
      );
    };

【讨论】:

    猜你喜欢
    • 2020-07-25
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多