当功能组件的状态更改时,我的 React 页面会重新加载。从技术上讲,只有组件应该重新渲染,而不是页面被重新加载
My React Page reloads when Functional Component's state is changed. Technically only the component should be rerender but instead the Page gets reload
组件树:
--> CampaignPage (Page reloaded)
--> CampaignHeader
--> UpdateCampaignForm (Want only this component to re-render on state update)
我的组件“UpdateCampaignForm”的代码如下:
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>❌</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
我的目标是在我从 campaignResources 中删除项目时重新呈现组件而不重新加载页面。此外,每次我尝试从 campaignResources 列表中删除元素时,页面都会重新加载。
如果您在从 campaignResources 中删除项目时在 Campaign Page 中设置了任何依赖项,那么它可能会生效。
所以也请分享您的 CampaignPage 代码。
看来您在 form
中有一个 button
用作提交和刷新页面。
我建议将 type='button'
属性添加到您的 button
或将其移到 form
元素之外,这将阻止刷新。
组件树:
--> CampaignPage (Page reloaded)
--> CampaignHeader
--> UpdateCampaignForm (Want only this component to re-render on state update)
我的组件“UpdateCampaignForm”的代码如下:
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>❌</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
我的目标是在我从 campaignResources 中删除项目时重新呈现组件而不重新加载页面。此外,每次我尝试从 campaignResources 列表中删除元素时,页面都会重新加载。
如果您在从 campaignResources 中删除项目时在 Campaign Page 中设置了任何依赖项,那么它可能会生效。 所以也请分享您的 CampaignPage 代码。
看来您在 form
中有一个 button
用作提交和刷新页面。
我建议将 type='button'
属性添加到您的 button
或将其移到 form
元素之外,这将阻止刷新。