0

My react component is rendering multiple times in infinity loop. What am I missing?

Here is my code.

const DocViewer = ({ title, closeModal }) => {

    const [docsSimilares, setDocsSimilares] = useState([]);
    const baseUrl = '/docs'

    async function similares() {
        return await axios.get(`${baseUrl}/${title}`).then(data => setDocsSimilares(data.data.body.hits.hits[0]._source.documentos_similares))
    }
    
    similares().then(console.log(docsSimilares))

    return (
        <div class="row">
            <div class="column pdf">
                <h1>{title}</h1> 
                <PDFViewer url={sFileNameDemo} />
            </div>
            <div class="column semelhantes">
                <button onClick={closeModal} >Fechar</button>
                <p>{docsSimilares.map(doc => (
                    <div>
                        <p>{doc}</p>
                        <img alt={doc} src={doc} width="100%" />
                    </div>
                ))}</p>             
            </div>
        </div>
    );
}

export default DocViewer
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129

3 Answers3

2

When you call your similares() function you are setting state when calling setDocsSimilares. By setting state you trigger re-render, when you trigger re-render it calls your similares() function again, that changes the state... You got the idea :)

By simply calling similares() inside of your functional component - it executes on each re-render.

You cannot just simply call similares() the way you do. I think what you trying to achieve is to get data on first component mount, so you should use useEffect with empty array as second argument like so:

useEffect(() => similares().then(console.log(docsSimilares)),[])
Nikita Chayka
  • 2,057
  • 8
  • 16
0

If you are using hooks you need to understand useEffect

useEffect(() => similares().then(console.log(docsSimilares)),[])

The square brackets are where you add dependencies, if no dependencies it will only run on initializing "mounting" it is the same as componentDidMount() so that it will only fire the async request on load.

Jordan Davis
  • 378
  • 1
  • 4
  • 14
0

This code solved my problem:

    async function similares() {
    const simDocs = await axios.get(`${baseUrl}/${title}`).then(data => (data.data.body.hits.hits[0]._source.documentos_similares))
    setDocsSimilares(simDocs)
}

useEffect(() => {
                    similares().then(data => console.log(data))
                },[]);