Home > Net >  My React Page reloads when Functional Component's state is changed. Technically only the compon
My React Page reloads when Functional Component's state is changed. Technically only the compon

Time:02-21

Component Tree:

--> CampaignPage (Page reloaded)

   --> CampaignHeader

       --> UpdateCampaignForm (Want only this component to re-render on state update)

The code for my component called "UpdateCampaignForm" is as follows:

import React, { useState, useEffect } from 'react'
import { Modal, Button } from 'react-bootstrap';

const UpdateCampaignForm = ({ show, handleClose, campaignId, campaignData }) => {
    const [existingCampaign, setExistingCampaign] = useState({
        campaignName: campaignData.campaignName,
        campaignDescription: campaignData.campaignDescription,
        campaignCoverMedia: campaignData.campaignCoverMedia
    })
    const [campaignResources, setCampaignResources] = useState(campaignData.campaignResources);
    const [isLoading, setIsLoading] = useState(false);
    const [isError, setIsError] = useState({ value: true, msg: '' });

    console.log(campaignResources);

    const removeDocument = (index) => {
        campaignResources.splice(index, 1);
        setCampaignResources(campaignResources);
    }

    const handleChange = (e) => {
        const { name, value } = e.target;
        if (name === 'campaignResources' || name === 'campaignCoverMedia') {
            const filesArray = Array.from(e.target.files);
            if (filesArray.length > 10) {
                setIsError({ value: true, msg: 'You can upload maximum 10 files' });
                return;
            } else {
                for (var i = 0; i < filesArray.length; i  ) {
                    if (filesArray[i].size > 10500000) {
                        setIsError({ value: true, msg: 'One of your files have exceded the limit of 10MB' });
                        return;
                    }
                }

            }
            setIsError({ value: false, msg: '' });
            setExistingCampaign({ ...existingCampaign, [name]: Array.from(e.target.files) });
        }
        else {
            setExistingCampaign({ ...existingCampaign, [name]: value });
        }
    }

    const handleSubmit = () => {

    }
    return <>
        <Modal show={show} onHide={handleClose} size="lg" aria-labelledby="contained-modal-title-center" centered>
            <Modal.Header closeButton>
                <Modal.Title>
                    Update Campaign
                </Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <h1 className='text-center'>Campaign Title</h1>
                <form>
                    <div className="form-group">
                        <label htmlFor="campaign-name">Campaign Name <span className='text-danger'>*</span></label>
                        <input type="text" className="form-control" id="campaign-name" name='campaignName' placeholder="Type in Campaign Name" onChange={handleChange} required autoComplete="off" value={existingCampaign.campaignName} />
                    </div>
                    <div className="form-group">
                        <label htmlFor="campaign-description">Campaign Description <span className='text-danger'>*</span></label>
                        <textarea className="form-control" id="campaign-description" rows="5" name='campaignDescription' placeholder="Type in Campaign Description" onChange={handleChange} required value={existingCampaign.campaignDescription} />
                    </div>
                    <div className="form-group">
                        <label htmlFor="campaign-category">Campaign Category <span className='text-danger'>*</span></label>
                        <select className="form-control" id="campaign-category" name='campaignCategory' required value={campaignData.campaignCategory} disabled>
                            <option>Education</option>
                            <option>Medical</option>
                            <option>Rights</option>
                            <option>Disaster Relief</option>
                            <option>Animal Care</option>
                            <option>Environment</option>
                        </select>
                    </div>
                    <div className="form-group">
                        <label htmlFor="total-funding">Total Funding Needed <span className='text-danger'>*</span></label>
                        <input type="number" className="form-control" id="campaign-name" name='requiredFunding' placeholder="Enter Total Funding Needed" min={1} required value={campaignData.requiredFunding / Math.pow(10, 18)} disabled />
                    </div>
                    <div className="form-group">
                        <label htmlFor="campaign-cover-image">Campaign Cover Image</label><br />
                        <input type="file" id="campaign-cover-image" name="campaignCoverMedia" onChange={handleChange} accept='image/*' />
                    </div>
                    <div className="form-group">
                        <label htmlFor="campaign-resources">Campaign Resources</label> <br />
                        <input type="file" id="campaign-resources" name="campaignResources" multiple onChange={handleChange} data-max-size='1024' />
                        {isError.value && <h6 className='text-danger'>{isError.msg}</h6>}
                    </div>
                    <div className="container">
                        {campaignResources.map((document, index) => (
                            < div className="row border border-secondary m-1 p-1" key={index} >
                                <div className="col-md-1">
                                    <a href={`http://localhost:4545/${document.filePath}`} target='_blank' download>
                                        <img className='pdf-icon' src="http://localhost:3000/file-icon.png" />
                                    </a>
                                </div>
                                <div className="col-md-8">
                                    <span>{index} {document.filePath.split('/').pop()} </span>
                                </div>
                                <div className="col-md-3 text-right">
                                    <button className='btn' onClick={() => removeDocument(index)}><span>&#10060;</span></button>
                                </div>
                            </div>
                        ))}
                    </div>
                </form>
            </Modal.Body>
            <Modal.Footer>
                {isLoading && <h6>Loading...</h6>}
                {isError.value ?
                    <Button variant="secondary" onClick={handleSubmit} disabled>
                        Submit Request
                    </Button> :
                    <Button variant="primary" onClick={handleSubmit}>
                        Submit Request
                    </Button>
                }
            </Modal.Footer>
        </Modal>
    </>
}

export default UpdateCampaignForm

enter image description here

My goal is to re-render the component without the page getting reloaded when I remove the Item from campaignResources. Also, the page gets reloaded every time I try to remove an element from the campaignResources list.

CodePudding user response:

If you have set any dependency in Campaign Page when you remove the item from campaignResources then it might be effecting. So please share your CampaignPage code too.

CodePudding user response:

It appears that you have a button inside form which is acting as a submit and refreshing the page.

I would advise to add the type='button' attribute to your button or move it outside of your form which will prevent a refresh.

  • Related