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.