• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

187
Views
Implementing a function to swap array elements in React without mutating the original array

I am coding a react app in which a user can click a button to swap an item in an array with the item to its left. I wrote a function to implement this without mutating the original items array that is rendering on the page, but this function is not doing anything to my code, nor is it returning any errors.

Here is my app component, which defines the function swapLeft then passes that function down to the Item component as props:

import React, { useState } from "react";
import Form from "./components/Form";
import Item from "./components/Item";
import { nanoid } from "nanoid";
import './App.css';

function App(props) {
  const [items, setItems] = useState(props.items);

  function deleteItem(id) {
    const remainingItems = items.filter(item => id !== item.id);
    setItems(remainingItems);
  }

  function swapLeft(index) {
    const index2 = index - 1;
    const newItems = items.slice();
    newItems[index] = items[index2];
    newItems[index2] = items[index];
    return newItems;
  }

  const itemList = items
  .map((item, index) => (
    <Item
      id={item.id}
      index={index}
      name={item.name}
      key={item.id}
      deleteItem={deleteItem}
      swapLeft={swapLeft}
    />
  ));


  function addItem(name) {
    const newItem = { id: "item-" + nanoid(), name: name };
    setItems([...items, newItem]);
  }


  return (
    <div className="form">
      <Form addItem={addItem} />
      <ul className="names">
        {itemList}
      </ul>
    </div>
  );
}

export default App;

And the Item component:

import React from "react";
import {  Button, Card, CardContent, CardHeader } from 'semantic-ui-react'

export default function Item(props) {
    return (
        
      <Card>
        <CardContent>
         <CardHeader> {props.name}</CardHeader>
          <Button onClick={() => props.deleteItem(props.id)}>
            Delete <span className="visually-hidden"> {props.name}</span>
          </Button>
          </CardContent>
          <CardContent style={{ display: 'flex' }}>
             <i className="arrow left icon" onClick={() => props.swapLeft(props.index)} style={{ color: 'blue'}}></i>
            <i className="arrow right icon"  style={{ color: 'blue'}}></i>
           </CardContent>
        </Card>
        
    );
  }

Is there a better way for me to write this function and implement this? I suppose I could do something with the React setState hook, but this seemed like an easier solution. I am new to React so any insight would be helpful

about 3 years ago · Juan Pablo Isaza
2 answers
Answer question

0

The way React knows if the state has changed is whether the state is refers to an entirely different address in memory. In case of arrays, if you want React to rerender the page because the array in the state changed, you need to provide it an entirely new array. Modifying the existing array will not trigger the render process.

Basically, what you need to do is changed the last line of swapLeft function to

setItems(newItems)

If you want the changes to take effect immediately (which is what I guess you want to do here)

You can also use the return value from the function and change the state in another component, FYI.

EDIT:

I looked at this again, and your implementation of swap is also wrong, but even if you corrected it you still wouldn't see a change, unless you did what I mentioned above

The full correct function would be

 function swapLeft(index) {
    const index2 = index - 1;
    const newItems = items.slice();
    const temp = items[index];
    newItems[index] = items[index2];
    newItems[index2] = temp;
    setItems(newItems);
  }

about 3 years ago · Juan Pablo Isaza Report

0

Just to maybe clarify the previous one. If you don't call setState, your component doesn't rerender. This means that no matter what you do with those arrays, it won't be visible on the screen.

about 3 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error