【问题标题】:React Component keeps on RenderingReact 组件继续渲染
【发布时间】:2020-07-19 21:39:47
【问题描述】:

我有三个文件 App.jsCompanySelection.jsChart.jsCompanySelection 组件有一个下拉列表(公司名称列表),我从中获取值并希望将其传递给 Chart 组件以绘制一些图表。

但是我有一个烧瓶组件要调用,这里是两个文件的代码:

App.js

import React from "react";
import { CompanyContextProvider } from "./context";
import Dropdown from 'react-dropdown';
import 'react-dropdown/style.css';
import Header from "./Header";
import CompanySelection from "./CompanySelection/CompanySelection.js";
import Charts from "./Charts/Chart.js";
import axios from 'axios';

class App extends React.Component{

    state = {
                companies: [],
                firstCompany: {},
                firstCompanyName: ''
            };


  componentDidMount() {
    fetch('http://127.0.0.1:5001/algo/loc')
    .then(res => res.json())
    .then(data => {
    this.setState({companies: data,
                    firstCompany: data[0],
                    firstCompanyName: data[0].value}, () => 
    console.log(this.state.companies, this.state.firstCompany, this.state.firstCompanyName));
    console.log('')

  }).catch(function (error) {
    console.log(error);
  });
  }

  selectedValueHandler = (selectedValue) => {
    this.setState({
        firstCompanyName: selectedValue
    })
}

  render() {
    const  selectedValue  = this.state.firstCompanyName;
    console.log('change value',selectedValue)
    return (
        <div className="app">
          <Header/> 
          <CompanySelection companies= {this.state.companies} selectedCompany={this.state.firstCompany} setSelectedCompany={this.state.firstCompanyName} selectedValueHandler = {this.selectedValueHandler}/>
          <Charts companies= {this.state.companies} selectedCompany={this.state.firstCompany} setSelectedCompany={selectedValue}/>

        </div>
        );
  }
} ;

export default App;

Chart.js

import {  h, render, Component } from 'preact';
import style from './style.css';
import { VictoryChart, VictoryLine, VictoryScatter, VictoryLabel} from 'victory';
import { useContext } from "preact/hooks";
import { CompanyContext } from "../context";

class Charts extends Component {

    constructor(props) 
    { 
        super(props); 
    } 

    state = {
                anomalies: [],
                dates: [],
                currentcomp: ''
            };


  render(_, { value }) {

    const companies = this.props.companies;
    const selectedCompany = this.props.selectedCompany; 
    const setSelectedCompany = this.props.setSelectedCompany;
    console.log('list of companies chart', companies)
    console.log('chart input', setSelectedCompany)

    const start_date = "2017-01-01"
    const end_date = "2020-01-01"

    const url = 'http://127.0.0.1:5001/algo/anom_score/'+setSelectedCompany+','+start_date+','+end_date

    fetch(url)
    .then(res => res.json())
    .then(data => {
    this.setState({anomalies: data,
                   dates: data['Anomaly Date']}, () => 
    console.log('Anomalies',this.state.anomalies));

  }).catch(function (error) {
    console.log(error);
  });

    if (typeof setSelectedCompany !== 'undefined') {
        var comp = setSelectedCompany;
    }
    else {
        var comp = '';
    }
    console.log("comp", comp);
    return (
        <fragment>
            <div class={style.chart}>
            <div className="content" dangerouslySetInnerHTML={{__html: this.state.anomalies}}></div>
                <VictoryChart domain={[0, 10]}>
                  <VictoryLabel text={comp} x={225} y={30} textAnchor="middle"/>
                  <VictoryLine
                    style={{ data: { stroke: "blue", strokeWidth: 3 } }}
                    y={(d) => d.x}
                  />
                  <VictoryScatter
                    symbol="star"
                    size={8}
                    style={{ data: { fill: "red" }}}
                    data={[{ x: 5, y: 5 }]}
                  />
                  <VictoryScatter
                    symbol="circle"
                    size={8}
                    style={{ data: { fill: "red" }}}
                    data={[{ x: 7, y: 7 }]}
                  />
                </VictoryChart>
            </div>
        </fragment>
    );
  }
}

render(<Charts />, document.body);
export default Charts;

我已尝试放置以下代码行:

const companies = this.props.companies;
const selectedCompany = this.props.selectedCompany; 
const setSelectedCompany = this.props.setSelectedCompany;
console.log('list of companies chart', companies)
console.log('chart input', setSelectedCompany)

componentDidMount() 内部并尝试获取值,但无法检索值并且fetch(url) 永远不会被触发。

然而,在render(_,{value}) 函数中放置同样的东西似乎工作得很好。但是组件继续渲染(无限地),因此更改下拉值会使 API 调用从烧瓶中变得非常缓慢。

我对 React JS 很陌生,所以无法理解我是否犯了一个概念性错误?或者我怎样才能停止重新渲染?

我尝试了多种解决方案,但似乎没有任何效果/

附:这篇文章可以看作是这篇文章的延续:Dropdown Value not passing from one component to the other - React JS,如果需要CompanyContext.js代码,可以参考这篇文章

【问题讨论】:

  • 嗨。您不应该使用 fetch 或任何导致代码的副作用,或在 render 方法中使用 setState。调用 setState 将导致组件重新渲染,并且在重新渲染时您再次调用 setState,这会导致无限循环。将获取相关代码移至 Charts 组件的 componentDidMount。它应该可以工作。

标签: javascript reactjs


【解决方案1】:

您需要将代码放在componendDidUpdate 中,因为当您更改App.js 中的状态时,您的componentDidUpdate 每次都会触发。

fetchData(){
 const companies = this.props.companies;
    const selectedCompany = this.props.selectedCompany; 
    const setSelectedCompany = this.props.setSelectedCompany;
    console.log('list of companies chart', companies)
    console.log('chart input', setSelectedCompany)

    // fetch(URL) AND SET STATE
      ........

}

componentDidMount(){
  this.fetchData(); // INITIAL FETCH
}

componentDidUpdate(prevProps){
  if(prevProps.selectedCompany !== this.props.selectedCompany){
    this.fetchData();  // FETCH WHEN PROPS CHANGE
  }
}

【讨论】:

  • 它说fetchData 没有在componentDidMount 函数中定义,为什么会这样?而且就像我提到的那样,CompanySelection.js 发生了变化,但我猜这应该不是问题
  • this.fetchData() 工作。已编辑您的答案。虽然有效。谢谢!
  • @DebadriDutta 是的,应该是this.fetchData(),感谢您的编辑,如果您正在寻找它,请不要忘记将其标记为答案:)
【解决方案2】:

您正在调用渲染函数中的 api 并设置一些状态。它会无限循环

1) 首先是渲染方法调用

2) 它击中 asi 并设置状态

3) 随着状态的改变,它再次重新渲染并设置状态

4) 循环继续进行

尝试让 api 在 componentDidMOunt() 中命中

【讨论】:

    猜你喜欢
    • 2020-12-12
    • 2018-06-16
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 2021-07-05
    • 2021-06-07
    • 2014-12-18
    相关资源
    最近更新 更多