简体   繁体   中英

useEffect is not rendering an array on DOM

I am populating an array with dummy data and once it is done, using useEffect, i'm trying to delete the the element on first index and update it on the DOM. The array is being updated on console but the changes doesn't reflect on DOM.

import './App.css';
        import { useState,useEffect } from 'react';
        import {faker} from '@faker-js/faker'
        function App() {
        
          var catsarray = []
          const [cats, changecat] = useState(()=>{
            for (let index = 0; index < 10; index++) {
              catsarray.push(faker.animal.cetacean())
            }
        
            return catsarray
          })
        
          useEffect(()=>{
           
          },[cats])
        
          const removecat = () => {
         
            cats.shift()
            changecat(cats)
          
          }
           
         return (
           <div className="App">
              <h1> List of cats </h1>  
                    <div className='wrapper'>
                    <ul>
                    <>
                    {catsarray.length > 2 ? 
                    cats.map((title, index)=>(
                       <li key={index}> {index} : {title} </li> 
                    )) : 'Array is empty' } 
                    </>
                  
                    </ul>
                    </div>
                    <button title='button' onClick={removecat}> Click me </button> 
                   
        
            </div>
          );
        }
        
        export default App;

看看这张图片

The reason is like @Jacob Smit said:

React uses referential comparisons to determine whether or not a value has changed. If you mutate (change) the state and provide it back to the setState function react sees the same value as it already has stored and thinks there is no operation to be carried out

So you need to use a different refernece when mutating a state

for example

// assign a new array 
let tempCats = [...cats]

// operate this new array
tempCats.shift()

// set the new array to state
changecat(tempCats)

Or like @Jacob Smit's suggestion

changecat(cats => cats.filter((_, i) => i !== 0))

a example from your question with a little modify

import React from "react"
import { useState, useEffect } from 'react';

function App() {
    var faker = ["steve", "john", "cat", "dog", "alex", "big"]

    var catsarray = []
    const [cats, changecat] = useState(() => {
        for (let index = 0; index < faker.length; index++) {
            catsarray.push(faker[index])
        }

        return catsarray
    })

    useEffect(() => {
    }, [cats])

    const removecat = () => {
        let tempCats = [...cats]
        tempCats.shift()
        console.log(tempCats)
        changecat(tempCats)

        // or @Jacob Smit's suggestion
        //changecat(cats => cats.filter((_, i) => i !== 0))
    }

    return (
        <div>
            <h1> List of cats </h1>
            <div>
                <ul>
                    <>
                        {cats.length > 2 ?
                            cats.map((title, index) => (
                                <li key={index}> {index} : {title} </li>
                            )) : 'Array is empty'}
                    </>
                </ul>
            </div>
            <button title='button' onClick={removecat}> Click me </button>
        </div>
    );
}

export default App;

a code snippet display

 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <div id="root"></div> <script type="text/babel"> function App() { var faker = ["steve", "john", "cat", "dog", "alex", "big"] var catsarray = [] const [cats, changecat] = React.useState(() => { for (let index = 0; index < faker.length; index++) { catsarray.push(faker[index]) } return catsarray }) React.useEffect(() => { }, [cats]) const removecat = () => { let tempCats = [...cats] tempCats.shift() console.log(tempCats) changecat(cats => cats.filter((_, i) => i.== 0)) } return ( <div> <h1> List of cats </h1> <div> <ul> {cats?length > 2. cats,map((title: index) => ( <li key={index}> {index}: {title} </li> )); 'Array is empty'} </ul> </div> <button title='button' onClick={removecat}> Click me </button> </div> ). } </script> <script type="text/babel"> ReactDOM,render( <App></App>. document;getElementById("root")); </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM