正在开发一个 MERN 应用程序,该应用程序使用 Vite 作为前端并使用 React。我使用 useEffect 挂钩从数据库中获取数据,其中数据列在表中。控制台中没有错误或警告,但当我控制台日志时,刷新页面时似乎 useEffect 挂钩被调用两次。 下面是我的代码:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const OperatingSites = () => {
const [siteData, setSiteData] = useState([
{ location: '', type: '', address: '' }
]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('http://localhost:5000/operatingSite');
const fetchData = response.data;
setSiteData([...fetchData, { location: '', type: '', address: '' }]);
} catch (error) {
console.error('Error fetching data:', error);
}
};
console.log("UseEffect");
fetchData();
}, []);
const handleInputChange = (index, event) => {
const { name, value } = event.target;
const newData = [...siteData];
newData[index][name] = value;
setSiteData(newData);
// Automatically add a new row if editing the last row and it's not empty
if (index === newData.length - 1 && newData[index].location && newData[index].type && newData[index].address) {
addEmptyRow();
}
};
const addEmptyRow = () => {
setSiteData([...siteData, { location: '', type: '', address: '' }]);
};
const generateRows = () => {
return siteData.map((site, index) => (
<tr key={index}>
<td>
<input
type="text"
className="w-full border-none focus:ring-transparent text-center"
placeholder="Enter location"
name="location"
value={site.location}
onChange={(e) => handleInputChange(index, e)}
/>
</td>
<td>
<select
className="w-full border-none focus:ring-transparent text-center"
name="type"
value={site.type}
onChange={(e) => handleInputChange(index, e)}
>
<option value="">Choose...</option>
<option value="Primary">Primary</option>
<option value="Secondary">Secondary</option>
</select>
</td>
<td>
<input
type="text"
className="w-full border-none focus:ring-transparent text-center"
placeholder="Enter address"
name="address"
value={site.address}
onChange={(e) => handleInputChange(index, e)}
/>
</td>
</tr>
));
};
const handleSubmit = async () => {
const filteredData = siteData.filter(site => site.location && site.type && site.address);
try {
await axios.post('http://localhost:5000/operatingSite', filteredData);
alert('Data submitted successfully');
} catch (error) {
console.error('Error submitting data:', error);
}
};
return (
<div className="flex">
<div className="w-full pb-20 pt-8 pr-28 pl-28">
<div className="relative overflow-hidden ">
<table className="w-full text-center border border-[#52B14A] ">
<thead className="bg-[#00bdf6] h-10">
<tr>
<th className="py-2">Location</th>
<th className="py-2">Primary/Secondary</th>
<th className="py-2">Address</th>
</tr>
</thead>
<tbody className="bg-transparent ">
{generateRows()}
</tbody>
</table>
<button onClick={handleSubmit} className="mt-4 p-2 bg-blue-500 text-white">
Submit Changes
</button>
</div>
</div>
</div>
);
};
export default OperatingSites;
如您所见,我在钩子内有一个控制台日志来检查它何时被调用:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const OperatingSites = () => {
const [siteData, setSiteData] = useState([
{ location: '', type: '', address: '' }
]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('http://localhost:5000/operatingSite');
const fetchData = response.data;
setSiteData([...fetchData, { location: '', type: '', address: '' }]);
} catch (error) {
console.error('Error fetching data:', error);
}
};
console.log("UseEffect");
fetchData();
}, []);
控制台输出将是:
问题是,当我检查console.log时,useEffect被触发两次。因此,代码会两次查询相同的数据,这是应该避免的。这不会影响项目,因为没有错误,但我想知道组件安装时 useEffect 运行两次背后的具体原因。
很可能您已开启 React StrictMode。
请检查您的应用程序是否带有标签
<StrictMode>
。严格模式会渲染组件两次(在开发中而不是在生产中),以便检测代码中的任何问题并向您发出警告(这可能非常有用)。这是预期的行为。