React Tips — HTML, State Arrays, and Images
Tags: react, webdev, programming, javascript
Published: 2021-01-21 21:43:46

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

### How to Pass HTML Tags in Props

There are several ways to pass HTML tags as props.

One way is to pass JSX expressions as props.

For instance, we can write:

```
myProp={<div><Foo />Some String</div>}
```

We can also pass in an HTML string:

```
myProp="<div>This is some html</div>"
```

Then we can render it as HTML by writing:

```
<div dangerouslySetInnerHTML={{ __html: this.props.myProp }}></div>
```

We set the `dangerouslySetInnerHTML` prop to render HTML as-is.

It only works with simple HTML and not JSX expressions, components, or other things.

We can also pass in an array of JSX elements:

```
myProp={["foo", <span>Some other</span>, "bar"]}
```

We have both strings and HTML in our `myProp` array.

We can then render this array the way we want.

Also, we can pass in components as the children of another component.

For instance, we can write:

```
<Foo>
  <div>Some content</div>
  <div>Some content</div>
</Foo>
```

We have the `Foo` component that’s wrapped around 2 divs.

In `Foo` we can render the components inside by referencing `this.props.children` for class components.

And in function components, we get the `children` property from the props parameter, which is the first one.

We can also use a fragment:

```
<MyComponent myProp={<React.Fragment>This is an <b>HTML</b> string.</React.Fragment>} />
```

Then we can pass in multiple elements without rendering a wrapper.

### Implement Authenticated Routes in React Router

We can implement authenticated routes with our own components.

For instance, we can write:

```
const PrivateRoute = ({ component: Component, authed, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) => authed
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
  )
}
```

We created our own `PrivateRouter` component that takes the component that we want to protect.

We renamed the `component` prop to `Component` to make it uppercase.

Then we render the component if authentication credentials are valid.

Otherwise, we return the `Redirect` component to redirect to an unprotected page.

Then we can use it by writing:

```
<PrivateRoute authed={this.state.authed} path='/profile' component={Profile} />
```

We pass in the component that we want into `PrivateRouter` to protect it.

### React.cloneElement vs this.props.children

We need to use `React.cloneElement` if we need to do anything other than rendering the children components.

This is because `this.prop.children` is only a descriptor of the children.

For instance, if we have the following:

```
render() {
  return(
    <Parent>
      <Child>First</Child>
      <Child>Second</Child>
      <Child>Third</Child>
    </Parent>
  )
}
```

Then to add a prop to it, we need to write:

```
render() {
  return (
    <div>
      {React.Children.map(this.props.children, child => {
        return React.cloneElement(child, {
          onClick: this.props.onClick })
      })}
    </div>
  )
}
```

We’ve to call `React.cloneElement` to make a clone of each child to add an `onClick` handler to each child component.

### Push into State Array

We can puts into a state array by concatenating the new entries to it.

This way, we don’t mutate the original array.

We don’t want to change the original since it’ll be overwritten on the next render.

For instance, we can write:

```
const arr = this.state.myArray.concat('new');
this.setState({ myArray: arr })
```

We can also use the spread operator:

```
this.setState({ myArray: [...this.state.myArray, 'new'] })
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] })
```

The first one adds a single entry as we have above.

The 2nd merged the 2nd array into the first one and return it.

If we need to set the new array value based on the current array’s value, we can call `setState` with a callback that returns a new array based on the previous one.

For instance, we can write:

```
this.setState(prevState => ({
  myArray: [...prevState.myArray, "new"]
}))
```

We return the state with a new array.

### Load Local Images with React

We can load local images by importing the image as a module.

For instance, we can write:

```
import React from 'react';
import logo from './logo.png';

function Header() {
  return <img src={logo} alt="Logo" />;
}
```

We import the image as a module and we put it straight into the `src` prop.

We can also do the same with `require` :

```
<img src={require('./logo.png')} />
```

### Conclusion

We can add images by importing them.

There are several ways to pass HTML as props.

`React.cloneElement` is required for adding props to children.

There are several ways to push new data to a state array.