Home > front end >  unable to assign values inside a forLoop
unable to assign values inside a forLoop

Time:11-03

I am trying to assign a random value to the "customStyle.top" inside my for loop, but the customStyle.top/customStyle.Left value is not changing randomly. My code is as below:

import React from "react";

const customStyle = {
  position: "absolute",
  top: "",
  left: "",
  zIndex: "initial",
  color: "green"
};

// Splitting Letters
const SplitText = React.memo(({ str }) => {
  return (
    <div>
      {str.split("").map((item, index) => {
        var randLeft = Math.floor(Math.random() * 1000);
        var randTop = Math.floor(Math.random() * 600);

        let letter = item;

        for (let i = 0; i < item; i  ) {
          customStyle.top =  randTop   "px";
          customStyle.left =  randLeft   "px";

          letter = letter   i;
        }
        console.log(customStyle.top);

        return (
          <div key={index} style={customStyle}>
            {letter}
          </div>
        );
      })}
    </div>
  );
});

export default SplitText;

link to my CodeSandbox: Click.!

CodePudding user response:

I fixed 2 bugs.

  1. You are splitting a string at "". So you will only get letters, never a string of multiple letters. That means using a loop here is nonsense!
  2. In your code you were using a reference to customStyle. Anytime you change a value you are changing it everywhere. Therefore copy the value or create a new one. Insert that value in your output.

Code

import React from "react";

// Splitting Letters
const SplitText = React.memo(({ str }) => {
  return (
    <div>
      {str.split("").map((item, index) => {
        const style = { 
          position: "absolute",
          top: Math.floor(Math.random() * 600)   'px',
          left: Math.floor(Math.random() * 600)   'px',
          zIndex: "initial",
          color: "green"
        };

        return (
          <div key={index} style={style}>
            {item}
          </div>
        );
      })}
    </div>
  );
});

export default SplitText;

CodePudding user response:

I think you've forgot to add the length keyword in your for loop.

Here is working code:

import React from "react";

const customStyle = {
    position: "absolute",
    top: "",
    left: "",
    zIndex: "initial",
    color: "green"
};

// Splitting Letters
const SplitText = React.memo(({ str }) => {
    return (
        <div>
            {str.split("").map((item, index) => {
                var randLeft = Math.floor(Math.random() * 1000);
                var randTop = Math.floor(Math.random() * 600);

                let letter = item;

                for (let i = 0; i < item.length; i  ) { // item.length
                    customStyle.top =  randTop   "px";
                    customStyle.left =  randLeft   "px";

                    letter = letter   i;
                }
                console.log(customStyle.top);

                return (
                    <div key={index} style={customStyle}>
                        {letter}
                    </div>
                );
            })}
        </div>
    );
});

CodePudding user response:

If you update a variable inside a component it wont re-render you should use useStateto track all state changes in a functional component, and since you are updating all elements in the loop you will need to use useEffect as well, this is because the changes will trigger a re-render, and you update again, that re-render and so on, infinite re-renders. The random need to be done only once this using the useEffect.

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

// Splitting Letters
const SplitText = React.memo(({ str }) => {
  const defaultCustomStyle = {
    position: "absolute",
    top: "",
    left: "",
    zIndex: "initial",
    color: "green"
  };

  const [customStyles, setCustomStyles] = useState([]);
  useEffect(() => {
    // Calc here the random values
    var randLeft = Math.floor(Math.random() * 1000);
    var randTop = Math.floor(Math.random() * 600);
    const auxCustomStyle = { ...defaultCustomStyle };
    for (let i = 0; i < str.split(""); i  ) {
      auxCustomStyle.top =  randTop   "px";
      auxCustomStyle.left =  randLeft   "px";
    }
    setCustomStyles((prevCustomStyles) => {
      prevCustomStyles.push(auxCustomStyle);
      return prevCustomStyles;
    });
  }, []);

  return (
    <div>
      {str.split("").map((item, index) => {
        let letter = item;
        for (let i = 0; i < item; i  ) {
          letter = letter   i;
        }
        return (
          <div key={index} style={customStyles[index]}>
            {letter}
          </div>
        );
      })}
    </div>
  );
});

export default SplitText;

Check if this works for you.

  • Related