React useEffect infinite loop when using dependencies + cleanup

I know this question gets asked a lot, but from the answers I could find I saw:

  • either no cleanup function in useEffect (so not my use case)
  • people not using dependencies at all (and a simple [] dependency would suffice)

So, here’s my code:

import { useEffect, useState } from "react";
import { Button } from "@material-ui/core";
import { CircularProgress } from "@material-ui/core";

export default function App() {
  const [tasks, setTasks] = useState<string[]>([]);

  useEffect(() => {
    const getTasks = () => {
      setTasks(["1", "2", "3"]);
    };
    getTasks();
    return () => {
      setTasks([]);
    };
  }, [tasks]);

  if (tasks.length === 0) {
    return <CircularProgress />;
  }

  return (
    <div>
      {JSON.stringify(tasks)}
      <Button onClick={() => setTasks([])}>Reset tasks data</Button>
    </div>
  );
}

CodeSandbox link: here. I removed the tasks from useEffect dependencies, because otherwise there’s an infinite loop and the browser tab may crash.

Let me explain what I want to achieve. This is just a snippet trying to mimic what I’m working on. I have a page with a table. This table is created by pulling some data from an API. So, the page loads, a table gets rendered. Then, under a table I have an “Add task” button. This brings up a little form to the front, where a new task can be created. I pass an onSubmit method to it, so when a user clicks “Create”, the POST request is made. And then I want the table to be updated.

To do this, I set the tasks to [], which are state, so component gets re-rendered, useEffect kicks in and re-downloads the tasks, which will contain the newly created one. And it works, but only if I don’t use a cleanup function in useEffect. If I do, I enter an infinite loop (because of the tasks dependency I guess).

As I don’t want to put axios calls in the example, this is the analogy:

  • getTasks in my app makes the API call
  • the button from the example is the button that opens a form to create a new task
  • didn’t want to add a table to the example, so just to show the data, I JSON.stringify() it

Anyway, to the question: I know I need the dependency to make the page refresh when I make the changes (in the example – click the button). How can I achieve what I want (re-render the page after the change to tasks is made) and retain the cleanup function in useEffect? (because if I remove it, everything works)

Not able to use HTML Input in Next.js if..else statement?

I am not able to use the search Input from my searchbar in Javascript if..else. I actually want to compare the Input Name of the searchbar with the database names using .filter(), but in next.js I am not allowed to use document to link it so I don’t know how to manage this.

(If I need to post also the test database just ask me to provide the information, but I do not think it is necessary here.)

import Head from 'next/head'
import styles from '../styles/Home.module.css'
import React from 'react'
import { bsctokendata } from "../pages/bscdatanew/data";



export default function Home(props) {


  const databalone = props.addressbalance;
  const datatransone  =  props.addresstransaction;
 
  // console.log(datatransone)

  return  (
    
    <ul>      
    <form onSubmit={submitToken}>
      <div className="search-box">
          <input type="text" className="search-by-item" name="name" placeholder="Search your Project..." id="name"></input>
          <button className="search-btn" type="submit" >Search</button>
      </div>
    </form>
      <h1>Address One</h1>
      {databalone.map((balance) => {
        return (
      <li>{(balance.result * 1e-18).toString()}</li>
      )})}
      <div>
      <h1>Address Two</h1>
      <div>
      {datatransone.map(function(d){
         return (
         <li>{d.result.map((r) => 
         <span>{r.from}</span>)}</li>
         )
       })}
       <h1>Address Three</h1>
        {datatransone.map(function(d){
         return (
         <li>{d.result.map((r) => 
         <span>{r.hash}</span>)}</li>
         )
       })}
      </div>
      </div>
    </ul>
  );
}


export async function getServerSideProps(context) {

        //  var input = document.getElementById("tokenname").value;


      let tokensame = bsctokendata.filter(function(element) {
        return (element.tokenName == `Here should be the name of the HTML Input`);
      })

      if (tokensame = true) {


    let newmap = tokensame.map(function(element){
      // return (element.whitelistWallets.map(function(r) { return (r)}))
      let wlunarush = element.whitelistWallets;
      return wlunarush;
      })

    // let contractaddress = '0xde301D6a2569aEfcFe271B9d98f318BAee1D30a4';

    let balance = newmap.flat().map(function(element){

      let bscbalance = 'https://api-testnet.bscscan.com/api?module=account&action=tokenbalance&contractaddress=0x0DBfd812Db3c979a80522A3e9296f9a4cc1f5045&address=' + element + '&tag=latest&apikey=E2JAJX6MAGAZUHSYIBZIEMKMNW9NZKPR7I';

    return bscbalance;
  })

    let transaction = newmap.flat().map(function(element){

      let bsctransaction = 'https://api-testnet.bscscan.com/api?module=account&action=tokentx&contractaddress=0x0DBfd812Db3c979a80522A3e9296f9a4cc1f5045&address=' + element + '&page=1&startblock=0&offset=1&endblock=999999999&sort=asc&apikey=E2JAJX6MAGAZUHSYIBZIEMKMNW9NZKPR7I';

    return bsctransaction;
  })
  
  // console.log(transaction)
  const addressbalance = await Promise.all(balance.map(u => fetch(u)))
  const addresstransaction = await Promise.all(transaction.map(e => fetch(e)))
  
  
  return {
    props: {
      addressbalance:  await Promise.all(addressbalance.map(r => r.json())),
      addresstransaction:  await Promise.all(addresstransaction.map(p => p.json())),
    }
  };

} else {
  console.log("No Token is entered yet")
}
}

Rerender Array Map on useState hook [duplicate]

<input id="words" onChange={(e) => {setWords(e.target.value.split(" "))}} />
  <br/>
  <button onClick={() => {setWords(words.sort())}}>Arrange</button>
  <button>Reset</button>
  <br/>
  <div>{words && words.map((word) => {
    return <button onClick={() => setWords(words.filter(item => item !== word))}>{word}</button>;
  })}</div>

The “Arrange” button on click is supposed to rerender the words.map function when setWords changes the state on words but the map does not rerender. Do I have to use useEffect to rerender the map?

Display Images from JSON Array using JavaScript

I tried to display an image from the image folder in JSON array to Javascript but I am not sure if I am getting the right path.
When the click event happens, everything works except for the image is not showing in the <img id “picture”>, the picture is not showing up in the img section of my HTML.

I tried to change the path to ../Images/room_1.jpg but it still not working.

FYI: I have a separate folder that stores images, both json and js are stored in the javascript folder. should I put the same image file in the javascript folder?

html

<h2>Select a Hotel</h2>
    <ul class ="hotels">
        <li><a href="#" id="marriott"> Marriott Hotel Rooms</a></li>
    </ul>
<h2 id="hotelName">Hotel</h2>
<h3>Adress: <span id="address"></span></h3>
<img id="picture">   

Hotel.json

{
"hotels": [
    {
        "name": "Marriott",
        "address": "098 hollywood Street",
        "picture": "room_1.jpg"
    }

JS

async function getHotelData() {

    try {

        const response = await fetch('Javascript//hotel.json')
        return await response.json() 

    } catch (error) {
        console.error(error)
    }

}

let hotelData = {}

getHotelData().then(data => hotelData = data)
 

const hotelEvent = document.querySelectorAll("a").forEach(a => {
    a.addEventListener('click', hotelInfo )
})

function hotelInfo(event) {
    let hotelChoice = hotelData.hotels.find(hotel => {
        return event.target.id === hotel.name.toLowerCase()
        return event.target.id === hotel.address.toLowerCase()
        return event.target.id === hotel.picture.toLowerCase()

        
    })
    console.log(hotelChoice)

    document.querySelector("#hotelName").textContent = `${hotelChoice.name} Hotel`
    document.querySelector("#address").textContent = `${hotelChoice.address}`
    document.querySelector("#picture").innerHTML = `${hotelChoice.picture}`



}

Regex for duplicate chars in a string after space

lets say i have a string looks like “ABCDEFGH ABCDEFG ABCDEF ABCDE EDCBA” and I need find mostly repeated and the longest chars in every substring “ABCDEFGH”, “ABCDEFG” etc.

In this case its would be “A” because its the only one occurs in every substring.

In this one “ABCDEFGH ABCDEFG ABCDEF ABCDE”, it would be “ABCDE”.

But in this case “132 12332 12312” the answer is “2”.

Is there any regex for something like this?
Or should I do something different?

I maked code for this with much of for loop (very much >_<) and it was working, but i used includes method and case “132 12332 12312” return 1 because it was finding only 1st repeated element.

If someone give me a hint how to do this I would be grateful.

Autocomplete options are only showing after unFocus/onFocus

const [value, setValue] = React.useState(null);
const [inputValue, setInputValue] = React.useState<string>('');
const [options, setOptions] = React.useState([]);
const { searchOrders } = useElasticAppSearch();

const debounceOnChange = React.useCallback(
    debounce((text, callback) => {
        searchOrders(text).then(callback);
    }, 200),
    []
);

useEffect(() => {
    if (inputValue === '') {
        setOptions(value ? [value] : []);
        return undefined;
    }

    debounceOnChange(inputValue, (filteredOptions: any) => {
        setOptions(filteredOptions);
    });

}, [inputValue, debounceOnChange]);

return (
    <Autocomplete
        sx={{
            width: 300, '.MuiOutlinedInput-notchedOutline': { borderRadius: theme.spacing(1) },
            '.MuiTextField-root': { background: 'white', borderRadius: theme.spacing(1) }
        }}
        filterOptions={(x) => x}
        autoComplete
        options={options}
        clearOnBlur={false}
        includeInputInList
        onChange={(event, newValue) => {
            setValue(newValue);
        }}
        onInputChange={(e, newInputValue) => setInputValue(newInputValue)}
        renderInput={(params) => (
            <TextField
                {...params} placeholder='Search Orders' fullWidth
            />
        )}
    />
);
};

I am having an issue where the options are not being displayed as I type in the Autocomplete, they are only being displayed after I unfocus and then focus (shown in picture 2). Where am I going wrong?
Typing

Unfocus/Onfocus

i need that my telegram bot on node js received and processed message that i send to him after query data

i need that my telegram bot on node js received and processed message that i send to him after query data, so i ask for help, cuz i am really have no idea how to solve it

if (query.data === "addToMega") {

      const nameOfPack = bot.sendMessage(chatId, "send message", {
        reply_markup: {
          force_reply: true,
        },
      });

      bot.onReplyToMessage(chatId, nameOfPack.message_id, (nameMsg) => {
        const name = nameMsg.text;
        
        bot.sendMessage(chatId, name);
      });
    }

Simple way in 2022 to do this

anyone know how to do better than this
https://www.456bereastreet.com/archive/201105/get_element_text_including_alt_text_for_images_with_javascript/ in 2022 ?

Thanks

code in the page :

var getElementText = function(el) {
    var text = '';
    // Text node (3) or CDATA node (4) - return its text
    if ( (el.nodeType === 3) || (el.nodeType === 4) ) {
        text = el.nodeValue;
    // If node is an element (1) and an img, input[type=image], or area element, return its alt text
    } else if ( (el.nodeType === 1) && (
            (el.tagName.toLowerCase() == 'img') ||
            (el.tagName.toLowerCase() == 'area') ||
            ((el.tagName.toLowerCase() == 'input') && el.getAttribute('type') && (el.getAttribute('type').toLowerCase() == 'image'))
            ) ) {
        text = el.getAttribute('alt') || '';
    // Traverse children unless this is a script or style element
    } else if ( (el.nodeType === 1) && !el.tagName.match(/^(script|style)$/i) ) {
        var children = el.childNodes;
        for (var i = 0, l = children.length; i < l; i++) {
            text += getElementText(children[i]);
        }
    }
    return text;
};

how to return string html as react child

i want to return my string as html for react child
assume string as "<div><span>test</span></div>"
and assume we have react function component like bellow

 function StrToElement({ str }) {  
 const element = new DOMParser().parseFromString(str, "text/html").body.childNodes[0];
 return <pre>{element}</pre>;
}

but above code throw this error :Error: Objects are not valid as a React child (found: [object Text])

Is there a way to stop a function from running if a certain button is clicked?

I have a small function for an AI player in Tic-Tac-Toe, but I dont want it to run at all if the player selects the “2 Player” version of the game.

function computerPlayer(){
        let computerPlayer = true;
       chooseRandomSpace();
        winCheck();
      }

function chooseRandomSpace() {
    let n = Math.floor(Math.random() * 9);
    if (game.entries[n] === null) {
      game.entries[n] = "O";
      return (document.getElementById(`space${n}`).innerText = "O");
    } else {
      chooseRandomSpace();
    }
  }

and this is the function that runs on 2 player button click:

function twoPlayerGame(){
    document.getElementById("playerNames1").style.display = "block";
    document.getElementById("playerNames2").style.display = "block";
    document.getElementById("numOfPlayers1").style.display = "none";
    document.getElementById("numOfPlayers2").style.display = "none";
}

Status code 401 whenever I try to ‘get’ using React Native Axios

I’m working on a React Native project that scans a food item’s barcode to get its data and then searches for it using the Spoonacular food API. So far, I can navigate to the scanner screen and it scans the barcode properly (following the code, it displays an alert with barcode type and data). However, when I try to perform a “get” request, using the axios library, with the API, it keeps on giving me Request failed with status code 401.

Below is my function for scanning, which is navigated to correctly, its just the API get that is not working.

  function ScannerScreen() {
    const [hasPermission, setHasPermission] = useState(null);
    const [scanned, setScanned] = useState(false);
    const baseUrl = 'https://api.spoonacular.com/food/products/upc/';
    const key = 'API key (omitted, but Ive checked this is correct)';
  
    useEffect(() => {
      (async () => {
        const { status } = await BarCodeScanner.requestPermissionsAsync();
        setHasPermission(status === 'granted');
      })();
    }, []);
  
    const handleBarCodeScanned = ({ type, data }) => {
      setScanned(true);
      alert(`Bar code with type ${type} and data ${data} has been scanned!`);
      //API fetching
      axios({
        method: "get",
        url: `${baseUrl}${data}&apiKey=${key}`,
      }).then((response) => {
        alert(response.data);
      }).catch((error) => {
        console.log(error);
      });
    };
  
    if (hasPermission === null) {
      return <Text>Requesting for camera permission</Text>;
    }
    if (hasPermission === false) {
      return <Text>No access to camera</Text>;
    }
  
    return (
      <View style={globalStyles.container}>
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
          //Change stylesheet later
          style={StyleSheet.absoluteFillObject}
        />
        {scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
      </View>
    );
  }

Any help would be much appreciated!

Variable Having Undefined Value after Assignment

    getData = () => {
        var id;
        $.getJSON('url', function(data) {
            id = data['id']
        });
        return id
    }

I am trying to fetch data from a url and save the id from the data as a seperate variable. However, the variable id seems to appear undefined even after being set as data['id']. Is there anything I can do to fix this?