当前位置: 首页 > 知识库问答 >
问题:

推送新URL时多次调用React组件呈现

赵刚豪
2023-03-14

我正在构建一个PhotoViewer,当用户按左键或右键时,它可以更改照片。我正在使用React、Redux、React router和React router Redux。当用户按下左键或右键时,我会做两件事,使用更新url。上下文replace()并发送一个操作来更新当前查看的照片,this。道具。调度(setPhoto(photoId))。我订阅状态更改以进行调试。

上面的每一行都会触发一个新的状态更改。因为我更新了currentlyViewedPhoto,所以发送操作会更新存储,而更新url会更新存储,因为react router redux会更新存储中的url。当我分派动作时,在第一个重新渲染周期中,组件的render函数会被调用两次。在第二个重新渲染周期中,组件的render函数被调用一次。这正常吗?以下是相关代码

class PhotoViewer extends Component {
  pressLeftOrRightKey(e) {
    ... code to detect that left or right arrow was pressed ...

    // Dispatching the action triggers a state update
    // render is called once after the following line
    this.props.dispatch(setPhoto(photoId)) // assume photoId is correct

    // Changing the url triggers a state update
    // render is called twice
    this.context.router.replace(url) // assume url is correct
    return
  }

  render() {
    return (
      <div>Test</div>
    )
  }
}

function select(state) {
  return state
}

export default connect(select)(PhotoViewer)

这是正常的渲染被调用三次?这似乎有些过头了,因为React将不得不进行三次DOM差异。我想这并不重要,因为一切都没有改变。我是这个工具集的新手,所以请随意询问关于这个问题的任何更多问题。

共有3个答案

逄征
2023-03-14

我明白了,这是一个老问题,但我也注意到了这个问题。就像唐纳德的回答中提到的,这似乎很正常。我尝试了三种方法来解决我的具体案例:

  • 我关闭了React DevTools插件,看看是否是重复消息的原因。
  • 我检查了不同的浏览器,看看这是否是问题所在。
  • 我创建了一个简短的测试来检查它是否发生在简单的组件上。

禁用React DevTools插件不会更改登录到控制台的消息数量。

换浏览器也没有效果。我试过Chromium和火狐。

即使是最简单的组件似乎也不止一次调用生命周期方法。

给定两个文件,App。js组件/TestComponent。js,如下所示:

// App.js

import React from 'react';
import './App.css';
import Test from './components/TestComponent';

functhtml" target="_blank">ion App()  {
  console.log('App render');
  return ( 
      <div>
        <Test />
      </div>
  
  );
}

export default App;
// ./components/TestComponent.js

import React, { Component } from 'react';


class Test extends Component {
  constructor(props) {
    console.log('Test constructed');
    super(props);
    
  }

  componentDidMount() {
    console.log('Test mounted');
  }

  componentDidUpdate() {
    console.log('Test updated');
  }

  render() {
    console.log('Test rendered');
    return (
      <div>
        <h1>Hello, world!</h1>
      </div>
    );
  }
}

export default Test;

生命周期测试方法称为多次测试。

  • 我使用CreateReact应用程序来设置应用程序

通过纱线开始,我在控制台中获得以下信息:

App render
TestComponent.js:7 Test constructed
TestComponent.js:7 Test constructed
TestComponent.js:20 Test rendered
TestComponent.js:20 Test rendered
TestComponent.js:12 Test mounted

至少对我来说,yarn注意到开发构建没有优化,运行yarn构建并将其与python-mhttp.server-目录构建一起提供给一个没有重复的消息。

至于为什么你得到的是三个而不是两个渲染,我不能说。我的建议是尝试构建这个应用程序,看看这个问题在生产构建中是否仍然存在。

如果您仍然遇到这个问题,您也可以接受Donald的建议,在acidComponentUpdate中实现逻辑。

谭云瀚
2023-03-14

我认为这是正常的。如果你没有明显的性能问题,我不会担心的。如果性能开始成为问题,如果您确定某些状态更改不会更改呈现的组件,您可以查看重写应该组件更新生命周期方法。

编辑:您还可以研究扩展React。PureComponent而不是React。组件如果您只需要在生命周期方法中进行粗略比较,则应更新组件生命周期方法。更多信息请点击这里。

杨波娃
2023-03-14

如果在三个不同阶段设置状态,则组件也将重新渲染三次。

除非在shouldComponentUpdate()中实现了条件呈现逻辑,否则setState()将始终触发重新呈现。

(来源)

如果您遇到性能问题,您可以在应该组件更新()中实现逻辑来防止不必要的重新呈现。

 类似资料:
  • 问题内容: 我正在构建一个PhotoViewer,当用户向左或向右按​​下时可以更改照片。我正在使用React,Redux,react-router和react- router- redux。当用户按下向左或向右按钮时,我会做两件事,我使用来更新网址,并调度一个操作来更新当前查看的照片。我正在订阅状态更改以进行调试。 以上每一行都会触发新的状态更改。因为我更新了,所以分派操作会更新存储,而更新UR

  • 我试图建立一个连接4的游戏,它有一个由7列组件组成的板组件,所有包含6个空间组件。每个列的上方都有一个拖放按钮,该按钮将用于将该件拖放到列中。为了在“红色”和“黑色”玩家之间交替,我创建了一个状态“redorblue”,它返回一个布尔值。 简而言之,当单击Drop按钮时,我希望切换“redorblue”的值,以跟踪轮到谁了。我已经将onClick函数设置为setState({redorblue:!

  • 我在一个表单上有一个TextField输入,问题是当我在它上键入时,刚刚键入的值的显示/呈现有一种延迟,我想防止这种延迟。 代码:

  • 我第一次尝试React钩子,一切似乎都很好,直到我意识到当我获取数据并更新两个不同的状态变量(数据和加载标志)时,我的组件(数据表)会呈现两次,尽管对状态更新器的两次调用都发生在同一个函数中。下面是我的api函数,它将两个变量都返回到我的组件中。 在普通的类组件中,您只需调用一次来更新状态,状态可能是一个复杂的对象,但“挂钩方式”似乎是将状态拆分为更小的单元,其副作用似乎是在单独更新时多次重新呈现

  • 我在useEffect钩子中调用一个GetAPI,以在组件装载之前获取数据,但是它多次调用API,并且我得到一个错误“多次API调用”。 输出: 请让我知道这是在组件使用useEffect钩子呈现之前从API获取数据的最佳方法。

  • 问题内容: 我是新来的世界,我有这样的话: 然后单击,您将被打印在控制台上。现在将行更改为: 现在点击该按钮,我希望它会被渲染。但事实并非如此。 我不确定为什么会这样。请注意,我在方法中有上面的代码。 问题答案: 您可能希望有一个状态组件,该状态组件在单击按钮之后在按钮旁边显示另一个组件。您需要做的就是跟踪按钮是否被单击: