Working With React Attributes

This is part 2 of our content about the basics of React. In this post we will pick up where we left of and talk about working with React attributes.

Now that you are in the same page with the concepts mentioned in the first part of this article, let’s move on.

Creating Variables

When we create a component in React, we can simply create a variable in JavaScript that will hold a construction function…or a class.

This constructor will receive the component’s properties as params:

“`jsx

function MyComponent (props) {

  return (

    <div className=”my-css-class”>

      {props.children}

    </div>

  );

}

“`

Now, other components can use it like this:

“`jsx

<MyComponent>

  The content

</MyComponent>

“`

And the DOM attribute will end with something like this:

“`html

<div class=”my-css-class”>

  The content

</div>

“`

You can relate to that too, to think about how we can add logic to our rendering components.

Everything between `{ }` will be treated by react as variables…not, actually, as JavaScript statements.

For example, you could have something like this:

“`jsx

  <div>

    {props.someVal.toUpperCase()}

  </div>

“`

Please notice that in this case, you are **counting** on receiving a `someVal` from props and also, that this will be a String…you should **not** simply trust the data you receive, but should validate everything prior to using them.

https://blog.vanhack.com/blog/everything-you-need-to-know-about-vanhacks-code-challenges/

Procedures

With that in mind, you can now execute procedures within those statements, including ternary conditions or maps.

“`jsx

  <div>

    {someBoolean === true ? “Ok” : “Not”}

  </div>

“`

In the end, every time your component renders, it will resolve to “Ok” or “Not” as the children/content of that div, based on `someBoolean`.

You can also use the return of functions:

“`jsx

function getSomeValue () {

  return 123;

}

  return <div>

    {getSomeValue()}

  </div>;

“`

But remember that functions in JavaScript can both be called or be passed as reference.

And here we find another point where people who are starting with React usually face some hard times.

For example:

“`jsx

function myClickListener () {

  return 123;

}

  return <div onClick={myClickListener}>

    Click me

  </div>;

“`

In this case, we are passing the function `myClickListener` down to the component’s `onClick` param. That function will be executed once the click event is triggered.

But…

“`jsx

function myClickListener () {

  return 123;

}

  return <div onClick={myClickListener()}>

    Click me

  </div>;

“`

Will not. Why?

Well…because while `myClickListener` is the reference to the function that WILL be called in the future…`myClickListener()` is the call of that function, which will be actually replaced by its return, 123. In the end, your component now is `<div onClick={123}>`, and `123` is not a function to be called when the click event is called.

And what about loops?

Well, you can’t have loops within these statements…but as you can have function calls, you can make use of the `Array.map` method.

You see, if you pass an Array to react, it will try and use its `toString` result, so, an array like `[1, 2, 3, 4]` will be rendered as `1,2,3,4` (the same as `[1, 2, 3, 4].toString()`. This, by itself, may be what you need in some cases.

But the Array.map will **return** a new Array containing the return of a function called for each item in the list.

“`jsx

const arr = [ “a”, “b”, “c” ];

  return <div>

    {arr.map(item => item.toUpperCase())}

  </div>;

“`

This will result in `<div>ABC</div>`.

There is one important point to make here, though.

Imagine you have a list of items that you want to use as child components:

“`jsx

function MyComponent (props) {

  const fruits = [

    { id: ‘1’, value: ‘Apple’ },

    { id: ‘2’, value: ‘Banana’ },

    { id: ‘3’, value: ‘Grapes’ }

  ];

  return <ul>

    {

      arr.map(item =>{

        return <li>

          { item.value }

        </li>;

      })

    }

  </ul>;

}

“`

The output will be something like:

“`html

<ul>

  <li>Apple</li>

  <li>Banana</li>

  <li>Grapes</li>

</ul>

“`

https://blog.vanhack.com/blog/5-steps-to-an-international-career-if-you-are-a-developer-with-no-experience/

Solving issues with React

That looks fine…until you see the warning message in your browser’s console.

Ah, classic.

That happens because in case something changes in your component and React has to re-render it…how is it supposed to know which line of the array changed?

Remember it compares the output to know what changed? What if the value of the item with the id 2 is now also “Apple”? How should react update the DOM elements? Should the second element’s innerHTML change to “Apple” or should the second element be removed and actually a new first element be added with the content “Apple”?

To solve that, you can add the `key` prop to items in your Array, like so:

“`jsx

 return <ul>

    {

      arr.map(item =>{

        return <li key={item.key}>

          { item.value }

        </li>;

      })

    }

  </ul>;

“`

Now, `key` will be used by React (and will NOT be rendered into your DOM element) to know each line.

When the user changes the second element’s value to “Apple”, its key will still be `2`. React now knows exactly what changed.

Also…that’s why you should NOT use `i`, the loop increment counter, as the key of your items…any change to the array and the `i` will always be `i`.

Let’s say, the user added an `{ id: 4, value: “Pineapple” }` to the top of the list.

When React re-render the list, your `i` would be 0 at this point and therefore, `Apple` will be replaced in the DOM output by `Pineapple`. Then, Banana will be replaced by Apple. Now Grape will be replaced by Banana, and a new line with Grape will be added at the end. The visual result will look the same, but that’s not what you wanted, right?

If your key is the `item.id`, then React will notice that it should only add a line to the top of the list and that’s all, no more changes shall be made to the DOM.

I hope you have found this article useful and fun.

This post was written by BrazilJS in partnership with VanHack

See how VanHack
can connect you to top-notch tech talent

Schedule a quick guide tour