我的react函数组件会不断地重新渲染自身,直到浏览器崩溃为止。
我唯一能找到的解决方案是在useEffect()末尾输入带有常量的[]。
function getNestedObject(nestedObj, pathArr) {
return pathArr.reduce(
(obj, key) => (obj && obj[key] !== "undefined" ? obj[key] : undefined),
nestedObj
);
}
function Genres() {
const [genreList, setgenreList] = useState(0);
useEffect(() => {
let results = "";
axios({
url: "https://api.themoviedb.org/3/genre/movie/list?",
method: "GET",
responseType: "json",
params: {
api_key: "00000000000",
language: "en-US"
}
}).then(result => (results = result.data.genres));
let a = [];
for (let i = 0; i < 10; i++) {
let name = getNestedObject(results, [i, "name"]);
a.push(name);
}
setgenreList(a);
console.log(genreList);
}, [genreList]);
return <div>test</div>;
}
我也尝试了不使用useEffect的情况,它给出了相同的循环结果。
我在渲染中放了<Genres />
。
答案 0 :(得分:6)
发生这种情况是因为您在打电话
setgenreList(a);
在useffect,genreList更改其状态,UseEffect再次运行
写作时
useEffect(() => {}, [genreList])
然后每次调用它的设置器 setgenreList
时都会调用它你可以写
useEffect(() => {
//code here
}, [])
答案 1 :(得分:1)
实际上,您每次都会生成一个空数组,并且每次都使用一个新生成的数组来更新状态,因此useEffect会无限循环(请检查[] === [])。另外,您在代码中还有一个明显的错误:状态更新根本不依赖于axios结果,因为您不必等待响应结果(在setgenreList(a)之后执行“ then”块)。在“然后”功能中使用状态更新。
答案 2 :(得分:1)
我想我会添加一个类似的实现的小答案,以及如何至少根据当前的实现(基于Rules of Hooks)处理条件
对于其中一个,您似乎完全按照文档进行操作,当调用useState
时,会为其提供默认值,并将其设置为0
,而应该将其设置为{空数组(因为之后要用它填充数组)
对于useEffect
,您不需要将第二个参数作为一个空数组(尽管这表明效果永远不要重新运行),您也可以将其保留为空,但是可以验证数组是否已经存在值时,您可以进行网络调用(您使用axios,但为简单起见,我改用本地fetch
)
const { useState, useEffect } = React;
const container = document.querySelector('#container');
const BreedList = () => {
const [breeds, setBreeds] = useState([]);
useEffect( () => {
if (!breeds.length) {
fetch( 'https://dog.ceo/api/breeds/list/all' )
.then( resp => resp.json() )
.then( result => {
setBreeds( Object.keys( result.message ) );
} );
}
}, [breeds] );
return (
<div>
<h1>Breeds</h1>
{ breeds.map( breed => <div key={ breed }>{ breed }</div> ) }
</div>
);
};
ReactDOM.render( <BreedList />, container );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="container"></div>