Going from Data to UI in React

Happening place to discuss this tutorial: http://www.kirupa.com/react/from_data_to_ui_in_react.htm
1 Like

Thank you for this wonderful article! There seems to be a mistake though I believe. When we add a key to each JSX component we push to the array, it should say:

 for (var i = 0; i < colors.length; i++) {
   renderData.push(<Circle key={i + colors[i]} bgColor={colors[i]}/>);
}

Otherwise, only a randomised circle will be displayed.

Dridge - the snippet I posted towards the end does something very similar:

for (var i = 0; i < colors.length; i++) {
  var color = colors[i];
  renderData.push(<Circle key={i + color} bgColor={color}/>);
}

I just created a color variable that stores the value of colors[i]. The end result between our code should be the same, right? Or am I overlooking something? It’s been one of those days :stuck_out_tongue:

Cheers,
Kirupa

1 Like

:joy: I totally overlooked the statement “var color = colors[i];”. Sorry and thanks again! :slight_smile:

1 Like

Hello,
I followed your step one by one as you did here, but I need to copy the background color of each button either to text color or background color of another component which is not a parent. I have create two rows of buttons; one to be used for text color and the other for the background color. How to use these background color from the parent to send them to other child. Hopefully you write the whole code. Thank you.

I am having difficulty visualizing what you are describing. Do you have a diagram that illustrates the arrangement of the components and what values you are trying to transfer to which destination? :slight_smile:

Yes, let’s say that the diagram like the following:

                           A
                         /   \
                        B     C
                      /   \
                     D     E

The D and E are the components that each include a class of creating a button and a list of color to style the background of the button, as you did here. B is a parent and instead of creating the next component as you did, I immediately placed the result of the list inside it. So I need to transfer the background color from either D or E to C. I have created a constructor in A to have a connection between B and C, but it didn’t work.I am beginner and need your help. Thank you.

Ah! That is exactly the kind of scenario Redux can help you with. Take a look at the Redux Introduction and then the article on how to integrate Redux into your React App :slight_smile:

And if redux seems overwhelming,

I have created a constructor in A to have a connection between B and C, but it didn’t work.

Seems like you were on the right track. You just need to manage everything through A, the common parent of them all. Here’s an example:

1 Like

A post was split to a new topic: React-redux error: Failed to execute ‘removeChild’ on ‘Node’

Morning,

I am attempting to get this set of circles to work, but am getting the error:

ReferenceError: renderData is not defined[Learn More]

in my console. I’ve tried to move the renderData variable to multiple locations, but it doesn’t seem to resolve the issue. Currently I have it just below var circleStyle & var colors in the “render(){” section of the the code. See below:

makingCirclesReact (1.4 KB)

If you have some time to point me in the right direction it would be appreciated. I’m sure I have the var defined in the wrong spot I just don’t know how to fix it.

Thanks :slight_smile:

Hi MountainTrailRover! You were really close. The code for render data and the array for populating it needs to live outside of the Circle component. Here is what the code inside the script tag should look like:

class Circle extends React.Component {
  render() {
    var circleStyle = {
      padding: 10,
      margin: 20,
      display: "inline-block",
      backgroundColor: this.props.bgColor,
      borderRadius: "50%",
      width: 100,
      height: 100
    };
    return (
      <div style={circleStyle}>
      </div>
    );
  }
}

var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363", "#85FFC7", "#297373", "#FF8552", "#A40E4C"];

var renderData = [];

for (var i = 0; i < colors.length; i++) {
  var color = colors[i];
  renderData.push(<Circle key={i + color} bgColor={color}/>);
};

ReactDOM.render(
    <div>
    {renderData}
    </div>,
    document.querySelector("#container")
  );

This should do the trick…hopefully! If it doesn’t work, please reply back and we can look at some other solutions.

Cheers,
Kirupa :smile:

Morning!

That worked beautifully, thanks for taking some time to reply. So the other variable for component Circle lives inside that component. Does the array get defined outside of it so you are able call multiple components?

Thanks again!

Cheers,
James

Are you referring to the circleStyle variable? If so, that one is localized just for that component. It is designed to specify how our circle looks. You can totally put that outside of the component as well to have other components use it if you want.

The reason the colors, renderData, and for loop are defined outside is that we need to populate renderData for rendering inside ReactDOM.render. If we defined all of them inside the Circle component, you can’t easily access them outside of it.

I explain a bit more about all of this in the following tutorial: Variable Scope Basics in JavaScript.

Hi!

I am absolutely LOVING this book so far! In this chapter, however, I ran into a problem that I don’t quite know how to figure out. I’m trying to get React to render the circles with different background colors found in our array, but Chrome keeps giving me the error:

Warning: React.createElement: 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 in, or you might have mixed up default and named imports.

I’m not trying to import/export anything particular (haven’t gotten to that part of the book yet!) I’ve Googled for a while, but haven’t found anything helpful that doesn’t have to do with importing/exporting. Can anyone help??

Can you share your code? That does sound like a strange error to be getting at this point :slight_smile:

Thanks,
Kirupa

<!DOCTYPE HTML>

<html>

<head>
  <meta charset="utf-8">
  <title>From Data to UI</title>
  <link rel="stylesheet" type="text/css" href="main.css">
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
</head>

<body>
  <div id="container"></div>
</body>

<script type="text/babel">
  var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363",
      "#85FFC7", "#297373", "#FF8552", "#A40E4C"];

  var renderData = [];

  for (var i = 0; i < colors.length; i++) {
      var color = colors[i];
      renderData.push(<Circle key={i + color} bgColor={color} />);
  }

  class Circle extends React.Component {
    render() {
      var circleStyle = {
        padding: 10,
        margin: 20,
        display: "inline-block",
        backgroundColor: this.props.bgColor,
        borderRadius: "50%",
        width: 100,
        height: 100,
      };

      return (
        <div style={circleStyle}>
        </div>
      );
    }
  }

  ReactDOM.render(
    <div>
      {renderData}
    </div>,
    document.querySelector("#container")
  );
</script>

</html>

(I hope this is formatted correctly.)

You formatted it correctly! :slight_smile:

The problem is very subtle. If you move your for loop just after the Circle class block, your code will work:

var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363", "#85FFC7", "#297373", "#FF8552", "#A40E4C"];

var renderData = [];

class Circle extends React.Component {
  render() {
    var circleStyle = {
      padding: 10,
      margin: 20,
      display: "inline-block",
      backgroundColor: this.props.bgColor,
      borderRadius: "50%",
      width: 100,
      height: 100
    };

    return (
      <div style={circleStyle}>
      </div>
    );
  }
}

for (var i = 0; i < colors.length; i++) {
  var color = colors[i];
  renderData.push(<Circle key={i + color} bgColor={color} />);
}

ReactDOM.render(
  <div>
    {renderData}
  </div>,
  document.querySelector("#container")
);

@senocular or @krilnon can go into much greater detail as to why this happens, but the Circle component you are pushing doesn’t exist when it is used before the actual Circle class declaration. This is all part of the JS quirks behind something known as hoisting. For classes, you must declare them before accessing/initializing them later in your code.

:slight_smile:

Wonderful, it worked! I actually ran into the same problem on my last project, but never figured out what the formal name for the issue is. Thank you so much for your help!!

1 Like