Waqas Ali
Waqas Ali

Reputation: 114

React - Component rendering multiple times

I'm using functional components and within that components I'm using useState so when I redirect to that component and log some text so it printed almost thousand times and this is very frustrating for me please help.

import React, { useState, useEffect } from 'react';
import Modal from 'react-bootstrap/Modal'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
import DatePicker from 'react-date-picker';
import axios from 'axios';
import useToken from '../../../account/useToken';
import TokenInfo from '../../../account/TokenInfo'

function CreateOrUpdateEvent(props) {
    const { token, setToken } = useToken();
    const [value, onChange] = useState(new Date());
    const [name, setName] = useState('');
    const [description, setDescription] = useState('');

    const {userId} = TokenInfo();
    console.log("Add Event Rendered");
    if(props.id != undefined)
    {
        const headers = {
            'Authorization': `bearer ${token}`
          }
        axios.get(`https://localhost:5001/Event/GetById/${props.id}`,        
       {
           headers: headers
       })
       .then(function (res) {
            setEventName(res.data.name);
            setEventDescription(res.data.description);
            setEventDate(res.data.eventDate);
       })
      .catch(function (error) {
        console.log(error);
      });
}

const setEventName = (name) => {
    setName(name);
}

const setEventDescription = (description) => {
    setDescription(description);
}

const setEventDate = (eventDate) => {
    var eventDate = new Date(eventDate);
    onChange(eventDate);
}

const saveEvent = () => {
    var event = {
        Id: props.id,
        Name: name,
        Description: description,
        EventDate: value,
        IsDeleted: false,
        CreatedDateTime: new Date(),
        UserId: userId
    }
    const headers = {
        'Authorization': `bearer ${token}`
      }
    axios.post('https://localhost:5001/Event/CreateOrUpdate', event, {
        headers: headers
      })
      .then(function () {
        props.onHide();
      })
      .catch(function (error) {
        console.log(error);
      });


}

return (
    <>
        <Modal
            {...props}>
            <Modal.Header>
                <Modal.Title>Create Event</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <Form.Group controlId="formBasicName">
                    <Form.Label>Name</Form.Label>
                    <Form.Control type="text" placeholder="Name" value={props.id != undefined ? name : ''} onChange={e => setName(e.target.value)} />
                </Form.Group>

                <Form.Group controlId="formBasicDescription">
                    <Form.Label>Description</Form.Label>
                    <Form.Control as="textarea" rows={3} value={props.id != undefined ? description : ''} onChange={e => setDescription(e.target.value)} />
                </Form.Group>

                <Form.Group controlId="formBasicDate">
                    <Form.Label>Date</Form.Label>
                    <div>
                        <DatePicker
                            onChange={onChange}
                            value={props.id != undefined ? value : new Date()}
                        />
                    </div>
                </Form.Group>
            </Modal.Body>
            <Modal.Footer>
                <Button variant="secondary" onClick={props.onHide}>
                    Close
            </Button>
                <Button variant="primary" onClick={saveEvent}>
                    Save Changes
            </Button>
            </Modal.Footer>
        </Modal>
    </>
)
};

export default React.memo(CreateOrUpdateEvent);

and I already remove StrictMode tag from index.js so please don't suggest that because it's not work for me.

enter image description here

Upvotes: 0

Views: 2926

Answers (2)

KOseare
KOseare

Reputation: 550

It is posible that your error is related to the axios query to https://localhost:5001/Event/GetById/${props.id}.

Remember that setting a new value into your state makes a new render, so every time the query ends, it'll be called again. You should put that query into a useEffect to just make it when the props.id changes:

function CreateOrUpdateEvent(props) {
    const { token, setToken } = useToken();
    const [value, onChange] = useState(new Date());
    const [name, setName] = useState('');
    const [description, setDescription] = useState('');

    const {userId} = TokenInfo();
    
    useEffect(() => {
      console.log("Add Event Rendered");
      if(props.id != undefined) {
        const headers = {
            'Authorization': `bearer ${token}`
          }
        axios.get(`https://localhost:5001/Event/GetById/${props.id}`,        
        {
            headers: headers
        })
        .then(function (res) {
            setEventName(res.data.name);
            setEventDescription(res.data.description);
            setEventDate(res.data.eventDate);
        })
        .catch(function (error) {
          console.log(error);
        });
      }
    }, [props.id]);

...

Upvotes: 1

Prebiusta
Prebiusta

Reputation: 479

The problem occurs, because every time you update a state, your axios function will be executed, updating the state again, causing an infinite loop.

Try to use the code below. Let me know if it made the trick.

useEffect(() => {
   const headers = {
        'Authorization': `bearer ${token}`
   }
   axios.get(`https://localhost:5001/Event/GetById/${props.id}`,        
   {
       headers: headers
   })
   .then(function (res) {
        setEventName(res.data.name);
        setEventDescription(res.data.description);
        setEventDate(res.data.eventDate);
   })
  .catch(function (error) {
    console.log(error);
  });
}, [props.id])

Upvotes: 1

Related Questions