React useEffect 渲染不止一次
React useEffect rendering more than once
我是 Hooks 的新手。我用 componentDidMount
.
编写了一个项目
现在我正在学习钩子并用钩子重写这个项目。我想先把数据拉出来打印在控制台上
但是,它渲染了 3 次。可能是因为我在useEffect
中使用了2个setState
。但是,在其中一个中,我将数据设置为数据数组,而在另一个中,我保留了微调器控件的加载值。我怎样才能像 componentDidMount
一样使用 useEffect
一次来提取数据并设置我的状态?
当我将控制台写入 useEffect
时,“React Hook useEffect 缺少依赖项:'data'。”警告和 returns 一个空列表。
顺便说一句,我删除了严格模式。
import React, { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const { data } = await axios.get("/data/data.json");
setData(data);
setLoading(false);
};
fetchData();
}, []);
console.log(data);
return <div className="App">App</div>;
}
export default App;
我认为 data
变量两次可能会导致与 linter 发生冲突。您可以重命名来自 API 调用的数据以防止警告:“React Hook useEffect 缺少依赖项:'data'”。“=18=]
您的组件将在每次状态更新时重新呈现,但是 useEffect
只会 运行 当您的依赖项发生变化时。由于它们不会更改,因此 API 调用只会发生一次。
为了证明这一点,您可以移动 useEffect
中的 console.log(result)
并查看它只记录一次。但是,请确保您在 result
而不是 data
上调用它,因为在调用 setData
.
之后直到下一次渲染才会更新状态
import React, { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const { data: result } = await axios.get("/data/data.json");
setData(result);
setLoading(false);
console.log(result); // runs once
};
fetchData();
}, [setData, setLoading]);
console.log(data); // runs 3 times
return <div className="App">App</div>;
}
export default App;
组件在每次状态更新后正常重新渲染。
因此,在您的示例中,它会在更新 data
的值时重新呈现,并在更新 loading
时再次呈现。
请检查此 demo 以检查每次状态更改后呈现的效果:
- 初始渲染
loading
设置为true
后
- 获取并设置
data
后
loading
后设置为false
我是 Hooks 的新手。我用 componentDidMount
.
现在我正在学习钩子并用钩子重写这个项目。我想先把数据拉出来打印在控制台上
但是,它渲染了 3 次。可能是因为我在useEffect
中使用了2个setState
。但是,在其中一个中,我将数据设置为数据数组,而在另一个中,我保留了微调器控件的加载值。我怎样才能像 componentDidMount
一样使用 useEffect
一次来提取数据并设置我的状态?
当我将控制台写入 useEffect
时,“React Hook useEffect 缺少依赖项:'data'。”警告和 returns 一个空列表。
顺便说一句,我删除了严格模式。
import React, { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const { data } = await axios.get("/data/data.json");
setData(data);
setLoading(false);
};
fetchData();
}, []);
console.log(data);
return <div className="App">App</div>;
}
export default App;
我认为 data
变量两次可能会导致与 linter 发生冲突。您可以重命名来自 API 调用的数据以防止警告:“React Hook useEffect 缺少依赖项:'data'”。“=18=]
您的组件将在每次状态更新时重新呈现,但是 useEffect
只会 运行 当您的依赖项发生变化时。由于它们不会更改,因此 API 调用只会发生一次。
为了证明这一点,您可以移动 useEffect
中的 console.log(result)
并查看它只记录一次。但是,请确保您在 result
而不是 data
上调用它,因为在调用 setData
.
import React, { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const { data: result } = await axios.get("/data/data.json");
setData(result);
setLoading(false);
console.log(result); // runs once
};
fetchData();
}, [setData, setLoading]);
console.log(data); // runs 3 times
return <div className="App">App</div>;
}
export default App;
组件在每次状态更新后正常重新渲染。
因此,在您的示例中,它会在更新 data
的值时重新呈现,并在更新 loading
时再次呈现。
请检查此 demo 以检查每次状态更改后呈现的效果:
- 初始渲染
loading
设置为true
后- 获取并设置
data
后 loading
后设置为false