Refresh a function following modifications to an array (such as exchanging values)

Looking to re-render a function after swapping array values, but the useEffect hook is not triggering it. I need assistance with this as I plan to integrate this code into my main project. Below are the JSX and CSS files attached. In App.js, I am creating a bar graph using an array and attempting to re-render the bar() function after value swaps.

import './App.css';
import "./components/Bar";
import Bar from './components/Bar';
import Footer from './components/Footer';
import Header from './components/Header';
import {useEffect} from 'react';

function App() {
  function bar(){
    return (
      arr.map((val, idx) => (
        <div
          className='element-bar'
          
          style={{
            height: `${val}px`,
            width: `${wid}px`,
            backgroundColor: "red",
            WebkitTransition: `background-color ${delay}ms linear`,
            msTransition: `background-color ${delay}ms linear`,
            transition: `background-color ${delay}ms linear`,
            transition: `${delay}ms`
          }} >
        </div>
      ))
    )
  }
  var arr = [10, 20, 30, 40, 50, 60];
  useEffect(() => {
    console.log(1);
    bar();
  },[arr,bar]);
  function swap(x,y){
    var t = x;
    x = y;
    y = t;
  }
  function change(){
    console.log(arr);
    swap(arr[0],arr[4]);
   }
  
  const wid = 4;
  const delay = 2;
  return (
    <div>
      <Header/>
      <button onClick={change} style={{ color: 'red' }}>Swap</button>
      <Bar/>
      <div className='array'>
        {
          bar()
        }
      </div>
      <Footer/>
    </div>
  );
}

export default App;

CSS

body {
    background-color: black;
}
.array {
    position: fixed;
    text-align: center;
    left: 250px;
    top: auto;
    bottom: 50px;
    display: flex;
    align-items: flex-end;
    flex-wrap: nowrap;
    width: 1260px;
}

.element-bar {
    display: inline-block;
    margin: 0 auto;
}

.sideNavbar {
    text-align: center;
    height: 100%;
    width: 210px;
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    background-color: rgb(29, 29, 29);
    overflow-x: hidden;
    padding-top: 20px;
    box-shadow: 0 4px 8px 0 rgba(81, 81, 81, 0.7), 0 6px 20px 0 rgb(81, 81, 81,0.7);
}

.sideNavbar h3 {
    font-size: 23px;
    text-decoration: underline;
    color: #818181;
    display: block;
    transition: 0.4s;
}

.sideNavbar h3:hover {
    color: #f1f1f1;
}

.sliderLabel {
    color: #f1f1f1;
}

.btn {
    margin: 10px 0;
    display: inline-block;
    padding: 6px;
    width: 100px;
    color: #818181;
    font-weight: 400;
    border: 2px solid #818181;
    background-color: transparent;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 100px;
    transition: 0.4s;
}

.btn:hover {
    color: #f1f1f1;
    border: 2px solid #f1f1f1;
    box-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
    text-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
}

.btndisabled {
    margin: 10px 0;
    display: inline-block;
    padding: 6px;
    width: 100px;
    border-radius: 100px;
    font-weight: 400;
    background-color: transparent;
    cursor: not-allowed;
    text-transform: uppercase;
    color: #f1f1f1;
    border: 2px solid #f1f1f1;
    box-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
    text-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
}

Answer №1

Give this a try

const defaultFunction = () => {
  const [array, setArray] = React.useState([10, 20, 30, 40, 50, 60])

  const swapItems = (item1, item2) => {
    let clonedArray = [...array]
    const temporary = clonedArray[item1]
    clonedArray[item1] = clonedArray[item2]
    clonedArray[item2] = temporary
    setArray(clonedArray)
  }

  const width = 4
  const timingDelay = 2

  return (
    <div>
      <button onClick={() => swapItems(0, 4)} style={{ color: 'red' }}>
        Swap
      </button>
      <div className="array">
        {array.map((value, index) => {
          console.log(value)
          return (
            <div
              className="element-bar"
              key={index}
              style={{
                height: `${value}px`,
                width: `${width}px`,
                backgroundColor: 'red',
                WebkitTransition: `background-color ${timingDelay}ms linear`,
                msTransition: `background-color ${timingDelay}ms linear`,
                transition: `background-color ${timingDelay}ms linear`,
                transition: `${timingDelay}ms`
              }}></div>
          )
        })}
      </div>
    </div>
  )
}

Answer №2

When working with React, it's important to remember that simply mutating an array or other data won't automatically trigger a re-render of your components. To ensure that React recognizes these changes, you should utilize useState. Additionally, consider using useCallback/useMemo to encapsulate functions and components defined within another component for better performance.

// Place useState at the beginning of your App() component
const [arr, setArr] = useState([10, 20, 30, 40, 50, 60]);
const bar = useCallback(() => {
    return (
    // ...
    )
}, [])
const swap = useCallback((x,y) => {
  var t = x;
  x = y;
  y = t;
}, [])
const change = useCallback(() => {
    console.log(arr);
    const newArr = [...arr]
    swap(newArr[0],newArr[4]);
    setArr(newArr) // Signaling React that the array has been updated and components need to be re-rendered
}, [])
// ...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: AppModule requires an array of arguments in order to function properly

Upon successfully compiling my Angular application and running ng serve, I encountered the following error in the browser console. AppComponent_Host.ngfactory.js? [sm]:1 ERROR Error: Arguments array must have arguments. at injectArgs (core.js:1412) at c ...

Webhost sending information to Windows sidebar gadget

Is there a way to showcase a list of information from a web host on a Windows sidebar gadget without using iframes? I've heard about using JavaScript AJAX (XmlHttpRequest) for this purpose, along with a refreshing function. Can anyone provide some gui ...

What is the best way to keep calling an AJAX function until it receives a response from a previous AJAX call

I am looking to continuously call my ajax function until the previous ajax call receives a response. Currently, the page is loading every second and triggering the ajax function, but I want it to keep calling the ajax function until the previous one has c ...

Best Way to Eliminate "#" Symbol from URL Address in UI-Router

My website URL is structured as follows: This is the index page where I utilize Angular UI-Router to navigate to different views, however, the URL retains the hash symbol (#) like this: Query: I am looking for a way to eliminate/remove the hash tag from ...

The many potentials of looping through Sass maps

My sass map contains a variety of color shades, and the full code can be found on Codepen: $pbcolors: ( pbcyan : ( 50: #E5F5FC, 100: #CCEBF9, 200: #99D7F2, 300: #66C3EC, 400: #33AFE5, 500: #009DBF, 600: #008CAB, 700: #007C98, 800: #006D85, 900: #005D72 ...

Remove the presence of a black square when selecting elements using CSS

Update: After some investigation, I discovered that the mysterious black square is actually a part of the scroll bar. By adding the following code snippet: select::-webkit-scrollbar { display: none; } The square no longer appears. Initially, my se ...

What is the best way to create a vertical connector line between Material UI icons in a list of list items?

How can I add a vertical connector line between avatar images in a React Material UI list item icons? Please see the sandbox URL for reference: https://codesandbox.io/s/9z2x527y6r [Please refer to the attached image below for an example of the desired ve ...

What is the best way to upload a file to Firebase Storage using React?

I am facing difficulty uploading a file to Firebase in order to retrieve its getDownloadURL. This is the code snippet I currently have: import React, {useState, useEffect} from 'react' import { Container, Button, Row, Col, Form, Alert } from &ap ...

Run module following a POST request

I am currently working on integrating real-time information transmission through sockets using socket.io, along with push notifications sent via the OneSignal platform. However, I have encountered an issue where placing both functionalities in the same mo ...

What is the best method to retrieve a nested JSON property that is deeply embedded within

I am facing an issue with storing a HEX color code obtained from an API in a Vue.js app. The object app stores the color code, for example: const app = {"theme":"{\"color\":\"#186DFFF0\"}"}. However, when I try to access the color prope ...

The Beginner's Guide to Mastering Ajax and Grails

As a newcomer to Grails and AJAX, I find myself struggling to understand the concept of AJAX with limited resources online. My current understanding is that in Grails, if I want to trigger a method in one of my controllers when a specific part of my HTML ...

Can the transition of the Chakra UI Menu component be customized?

Is it feasible to modify the transition of Chakra's Menu component List element using custom CSS or Chakra's built-in transitions? See more information at here ...

Something is not quite right when the page is loading in a Ruby on Rails application

In the process of developing a wiki clone, I am faced with an issue involving JavaScript. When I navigate to a specific page by clicking on a link, the JavaScript does not function properly until I refresh the page. The JavaScript aspect mainly involves an ...

I have the latitude and longitude for both the shop and user, and I am looking to display a list of shops in order based

Currently, I have the latitude and longitude for both my shop and the user. My objective is to display a list of shops that fall within the geographic area between the user's location and the shop's coordinates using Sequelize ORM. Can you provid ...

Issue with ReactJS Typescript: Cannot assign type 'number' to type '0, 8, 16, 24, 32, 40, or undefined'

I am looking to implement a grid from material-ui in react using typescript. You can view the live demo here. I have made adjustments to the example to make it work with typescript. Here is how my demo.jsx file looks like: import { withStyles } from &apo ...

Unable to reach elements that have been loaded through ajax with jQuery

I am facing an issue where I cannot access content loaded via ajax for modification. Unfortunately, I do not have access to the js file responsible for the initial load. Therefore, I need to create a separate function to alter the content. The required mo ...

Search for Azure Time Series Insights (TSI) data insights

Is there a way to access real-time data from Azure TSI using the TSI query API? I am currently utilizing the TSI JavaScript Client library, which provides two wrappers for the Query API. However, these wrappers only allow me to retrieve aggregate data li ...

Inspect the render function in the 'RestApi' class

I encountered the following error: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined ...

Implement tooltip functionality in ssr chart using echarts

A chart is generated using echarts on the server-side: getChart.ts const chart = echarts.init(null, null, { renderer: 'svg', ssr: true, width: 400, height: 300 }); chart.setOption({ xAxis: { data: timeData }, ...

Update a Div, Table, or TR element without the need for a page reload or Ajax usage

How can I refresh a div, table or <tr>? The data displayed is not coming from a database, it's just a simple error block and the value comes from Java-script. The issue arises when a user inputs a value in a textbox, the value gets stored in th ...