(Simple) Random Variables Changing after Mapping - ReactJS

Hey again all, I have an easy question (i’m sure) for you. This is in ReactJS.

Whats going on… I have a form

  1. onSubmit of the form I grab a dom div, and set innerHTML to a list of names (array).

  2. I map through the array of names and for each iteration I grab a random color, and random greeting from two separate arrays in my component state and insert them into the mapped names. via dom.

Now all of this works well except, each time I submit my form, the previously saved random variables change as well as the current. See Images ->

class Content extends Component {
  constructor(props) {
    super(props);
    this.state = {
      names: "",
      greetings: [
        "Well well, look who finally shows up.",
        "Boy am I glad to see you!",
        "Enter the dojo my friend.",
        "You arrived just in time!",
        "Now that you're back, we can party!"
      ],
      colors: ["#bb82f9", "#f4c3d5", "#fab916", "#61dafb", "#fc0d1c", "#84ffaf"]
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleSubmit = (e) => {
    e.preventDefault();

    const names = this.state.names.split(textAreaRegex);
    const nametagsDiv = document.getElementById('nametags');
    const greetings = this.state.greetings;
    const colors = this.state.colors;


    nametagsDiv.innerHTML = names.map(function(name, index) {
      var randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
      var randomColor = colors[Math.floor(Math.random() * colors.length)];
      console.log(randomColor);

      return `
        <div key=${index} class="nametags-group flex">
          <h1>${index + 1}.</h1>
          <button type="button" class="nametag" style="background-color:${randomColor}">${name}</button>
          <p class="greeting">${randomGreeting}</p>
        </div>`
    }).join('');
  }

the problem is in the function that you call to handle your submits. everytime you call the function its resetting all your variables. so you have to find a way to save where they wont be changed when ever you call that variable

i didnt really spend a tonne of time reading your code but it kinda looks like that might be the problem if things are changing on click when theyre not suppose to

I don’t understeand what you mean, by the variables are changing.

You function is doing exactly what you asked it to do:
1- onSubmit takes a list of names
2 - take the list of names, create a new array mapped from names with random values
3 - clean the content of nametagsDiv and insert the new mapped content.

pretty much each time you call onSubmit you create a totally fresh and new sets of data, you are not adding on top of what you have.


That said, you are not really leveraging the power of react.
What you want to achieve can be made more simple through splitting your UI in smaller components.
I suggest you to read thinking in react in the official docs to know a bit more about it.

The ideal (imho) for this would be to have a Parent component that holds in its state an array of information.
onSubmit will add into this array a new chunk of information.
then let another component uses this info as props to handle the display.

This way every time the parent changes its state the child will reflect this change.

A quick skeleton:

class Parent extends React.Component {
  state = {
    data: [{ name: "default", color: "red" }]
  };

  addNew = () => {
    const fakeNew = { name: "new", color: "blue" };

    this.setState({
      data: [...this.state.data, Object.assign({}, fakeNew)]
    });
  };

  render() {
    const { data } = this.state;
    return (
      <div>
        {data.map(el => (
          <Block key={el.name} title={el.name} color={el.color} />
        ))}
        <button onClick={this.addNew}>add new</button>
      </div>
    );
  }
}

const Block = ({ title, color }) => (
  <div>
    <p>
      {title} - {color}
    </p>
  </div>
);

demo here.

Hope it helps :+1: