I created a project with create-react-app,
and I am trying React hooks,
in below example,
the sentence console.log(articles)
runs endlessly:
import React, {useState, useEffect} from "react"
import {InfiniteScroller} from "react-iscroller";
import axios from "axios";
import './index.less';
function ArticleList() {
const [articles, setArticles] = useState([]);
useEffect(() => {
getArticleList().then(res => {
setArticles(res.data.article_list);
console.log(articles);
});
},[articles]);
const getArticleList = params => {
return axios.get('/api/articles', params).then(res => {
return res.data
}, err => {
return Promise.reject(err);
}).catch((error) => {
return Promise.reject(error);
});
};
let renderCell = (item, index) => {
return (
<li key={index} style={{listStyle: "none"}}>
<div>
<span style={{color: "red"}}>{index}</span>
{item.content}
</div>
{item.image ? <img src={item.image}/> : null}
</li>
);
};
let onEnd = () => {
//...
};
return (
<InfiniteScroller
itemAverageHeight={66}
containerHeight={window.innerHeight}
items={articles}
itemKey="id"
onRenderCell={renderCell}
onEnd={onEnd}
/>
);
}
export default ArticleList;
Why is it?How to handle it?
React useEffect compares the second argument with it previous value, articles in your case. But result of comparing objects in javascript is always false, try to compare [] === [] in your browser console you will get false. So the solution is to compare not the whole object, but articles.lenght
const [articles, setArticles] = useState([]);
useEffect(() => {
getArticleList().then(res => {
setArticles(res.data.article_list);
console.log(articles);
});
},[articles.length]);
It is simply because you cannot compare two array (which are simply) objects in JavaScript using ===. Here what you are basically doing is comparing the previous value of articleName to current value of articleName, which will always return false. Since
That comparison by reference basically checks to see if the objects given refer to the same location in memory.
Here its not, so each time re-rendering occurs. The solution is to pass a constant like array length or if you want a tight check then create a hash from all element in the array and compare them on each render.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With