首页 > 解决方案 > 超过最大更新深度。渲染方法中没有直接的函数调用

问题描述

我检查了有关此错误的其他 SO 线程,他们说您在渲染方法中有一些函数调用。但在这里我没有。

它会自动调用componentDidMount。我不知道,哪个部分在调用它。请帮忙

我的组件

class TeacherDashboard extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            questionPapers: ''
        };
    }
    componentDidMount() {
        this.props.removeError();
        apiCall('get', `${process.env.REACT_APP_BASE_URL}/api/questionpapers`, undefined) //fetch all question set
            .then(data => {
                if (!data.success) {
                    throw Error(data.message);
                }
                else {
                    this.setState({
                        isLoading: false,
                        questionPapers: data.questionPapers
                    })
                }
            })
            .catch(err => {
                this.setState({
                    isLoading: false
                })
                this.props.addError(err.message || 'something went wrong. please try again later.')
            });
    }

    deleteQuestionPaper = (questionPaperId) => {
        apiCall('delete', `${process.env.REACT_APP_BASE_URL}/api/questionpapers/${questionPaperId}`, undefined)
            .then(data => {
                if (!data.success) {
                    throw Error(data.message);
                }
                else {
                    this.setState({
                        questionPapers: this.state.questionPapers.filter((questionPaper) => questionPaper._id !== questionPaperId)
                    })
                }
            })
            .catch(err => {
                this.props.addError(err.message || 'something went wrong. please try again later.')

            });
    }


    render() {
        debugger
        let { isLoading, questionPapers } = this.state;
        let dashboard = questionPapers ? questionPapers.length > 0 ?
            <QuestionPaperInfo  questionPapers={questionPapers} deleteQuestionPaper={this.deleteQuestionPaper} /> :
            <div className='bg-danger h2 p-1' >No question paper found. please create one.</div> :
            null;
        return (
            <div className='mt-2'>
                {isLoading ? <p className='h1'>Loading......</p> : dashboard}
                <Link to='/teachers/newquestionpaper' className='btn btn-warning'>Add a new Question paper</Link>
            </div>
        )
    }
}

export default TeacherDashboard;

QuestionPaperInfo零件

const QuestionPaperInfo = (props) => {
    return (
        <table className="table table-hover text-center">
          <thead className="thead-dark">
            <tr>
              <th scope="col">S.N.</th>
              <th scope="col">Subject</th>
              <th scope="col">Class</th>
              <th scope="col">Total Questions</th>
              <th scope="col">Total Marks</th>
              <th scope="col">Action</th>
            </tr>
          </thead>
          <tbody>
          {props.questionPapers.map((questionPaper,i)=>{
             return <tr key={questionPaper._id||i}>
                <th scope='row'> {i+1}</th>
                <th><Link to={`/teachers/${questionPaper._id}`}>{questionPaper.subject}</Link></th>
                <th>{questionPaper.standard}</th>
                <th>{questionPaper.totalQuestions}</th>
                <th>{questionPaper.totalMarks}</th>
                <th className='text-danger' onClick={()=>props.deleteQuestionPaper.bind(null, questionPaper._id )}>Delete</th>
              </tr>
          })}
          </tbody>
        </table>
    )
}

export default QuestionPaperInfo

父组件

import React, { Component } from 'react';
import { withRouter } from "react-router-dom"

const withAuth = (ComponentToBeRendered)=>{
    class Authenticate extends Component {
        componentWillMount() {
            if (!window.localStorage.jwtToken) {
                debugger
                // console.log(this.props)
                this.props.addError('please signin first.');
                this.props.history.push('/auth/signin');
            }
        }
        componentWillUpdate(nextProps) {
            if (!window.localStorage.jwtToken) {
                this.props.addError('please signin first.');
                this.props.history.push('/auth/signin');
            }
        }

        render() {
            return <ComponentToBeRendered removeError={this.props.removeError} addError={this.props.addError} />
        }
    }
    return withRouter(Authenticate)
}

export default withAuth;

在 app.js 里面

render(){
   let WithHocTeacherDashboard = withAuth(TeacherDashboard);
   return
   <Route exact path='/teachers/me' render={props=> <WithHocTeacherDashboard addError={this.addError} removeError={this.removeError} />} /> 
}

addError它在 app.js中的方法失败

标签: reactjs

解决方案


Seems like your trying to setState in componentDidMountwithout setting a condition so basically every update runs the component again.

try entering logic of componentDidMount inside a condition comparing old props with new props.

like this

  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    // your logic
  }
} 

ou may call setState() immediately in componentDidUpdate() but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop. It would also cause an extra re-rendering which, while not visible to the user, can affect the component performance.

componentDidMount()


推荐阅读