1

i check the other SO threads about this error, they says that you have some function calling in render method. but here i don't have any.

it's automatically calling componentDidMount. i don't know,which part is calling it. please help

my component

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 component

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

parent component

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;

inside app.js

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

it's failing at addError method in app.js

Gouri Shankar
  • 129
  • 1
  • 2
  • 8
  • I see nothing particularly wrong in your code. I would try to look into the parent component. – Sulthan Mar 17 '19 at 20:37
  • i have updated the code. it's working properly if i remove `WithAuth`, but i need that functionality. – Gouri Shankar Mar 17 '19 at 21:41
  • I suspect triggering an action in `componentWillMount` is causing the problem. You should probably handle the whole concept differently. – Sulthan Mar 17 '19 at 22:08

1 Answers1

0

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()

fedesc
  • 2,554
  • 2
  • 23
  • 39
  • but how to stop this infinite loop. the above code will stop calling `setState` but it didn't stop the continuous rendering – Gouri Shankar Mar 17 '19 at 17:52