Home > Back-end >  How to use .splice() property at React?
How to use .splice() property at React?

Time:09-26

I'm new at React and in this case I'm trying to show a list of operations. I need to show only the LAST 10 operations of the list and im trying to do this using .splice() on the array. I tried a lot but couldn´t make it work. I'm getting the following error: TypeError: list is not iterable.

Any idea how to do this?

This is my component code so far:

export default function ListOperations(){
    const dispatch = useDispatch();
    // const list = useSelector((state) => state.operations);
    const [list, setList] = React.useState({});

    React.useEffect(async () => {
        try{
            const response = await axios.get('http://localhost:3000/operation');

            dispatch({
                type: 'LIST_OPERATIONS',
                list: response.data
            })
        }
        catch(e){
            swal("Error", e.message, "error");
        }
    }, []);

    const currentListCopy = [...list];

    if(currentListCopy >= 10){
        currentListCopy.splice(10);
        setList(currentListCopy)
    }


    return(
        <div>
            <div>
                <h2>OPERATIONS HISTORY:</h2>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Reason</th>
                        <th>Amount</th>
                        <th>Date</th>
                        <th>Type</th>
                    </tr>
                </thead>
                <tbody>
                    {list.map((oneOperation) =>
                        oneOperation ? (
                            <tr key={oneOperation.id}>
                                <td>{oneOperation.id}</td>
                                <td>{oneOperation.reason}</td>
                                <td>{oneOperation.amount}</td>
                                <td>{oneOperation.date}</td>
                                <td>{oneOperation.type}</td>
                            </tr>
                        ) : null
                    )}
                </tbody>
            </table>
        </div>
    );
};

CodePudding user response:

if(currentListCopy >= 10){
    currentListCopy.splice(10);
    setList(currentListCopy)
}

you're missing "length" :

if(currentListCopy.length >= 10){
    currentListCopy.splice(10);
    setList(currentListCopy)
} 

also, you shouldn't use promise inside useEffect https://dev.to/danialdezfouli/what-s-wrong-with-the-async-function-in-useeffect-4jne

CodePudding user response:

There are a couple of issues, which are causing the error and also, if the error is fixed, the fetched results will not be shown in the application.

Issue 1

const [list, setList] = React.useState({});

In the above code, you're initializing state as an object, which is causing the error list is not iterable, in the below code, when you're trying to use the spread operator to create an array of state object.

const currentListCopy = [...list];

Fix

You can fix this issue by initialing the list state as an empty array.

const [list, setList] = React.useState({});

Issue 2

The second issue is you're dispatching an action in the useEffect hook, but not getting the updated state from the store, since this line // const list = useSelector((state) => state.operations); is commented out. Since you're not fetching any state from store also nor updating the local state list, you'll not see any changes in the map function, as its empty, even though some data is being returned from the network in the API call.

Fix

If you wish to use the state from the store to update the local store, than you've to uncomment this line // const list = useSelector((state) => state.operations) and rename list to something else.

Also you need to move your splice code to the useEffect hook, so, whenever the list updated in the global state, your local state also updated accordingly.

React.useEffect(() => {
    if (Array.isArray(list) && list.length) { // assuming list is the global state and we need to ensure the list is valid array with some indexes in it.
      const currentListCopy = [...list];
      if(currentListCopy.length >= 10) { // as above answer point out
        currentListCopy.splice(10);
        setList(currentListCopy)
      }
    }
 }, [list]); // added list as a dependency to run the hook on any change in the list

Also, as above answer point out, you should avoid async functions in the useEffect.

  • Related