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.
Add Multiple Classes to a React Component
We can use the classnames
package to add multiple classes to a React component.
For instance, in the render
method or the function component, we can write:
const liClasses = classNames({
'main-class': true,
'active': props.active
});
return (<li className={liClasses}>{props.name}</li>);
We can also use template literals to do the same thing.
For instance, we can write:
<input className={`form-control rounded ${this.state.valid ? '' : 'error'}`} />
Fix the ‘Invariant Violation: Objects are not valid as a React child’ Error
We can fix the error by making sure that we have strings or components in between the opening and closing tags of a wrapper component.
For instance, if we’re rendering a string, we can write:
return (
<Item href={routeString}>
{breadcrumbElement}
</Item>
)
where breadcrumbElement
is a React element or component.
We can also replace the element or component with a string:
return (
<Item href={routeString}>
hello world
</Item>
)
If we have an array, we can write:
const photosList = photos.map((photo, i) => {
return (
<div>
<img src={photo.url} alt={photos.description} />
</div>
);
});
return (
{photosList}
);
These are all inside the render
method of a class component or a function.
We have an expression to render the photos
array into images by call map
with a callback that returns an img element.
Then we return that in our return
statement.
Fix the ‘A component is changing an uncontrolled input of type text to be controlled’ Error
We can fix the error by setting the value
prop of our input with a state.
To set the state, we pass an event handler to the onChange
prop to set the state when the input value changes.
For instance, we can write:
<input
className="input"
type="text"
value={this.state.name || ""}
name="name"
placeholder="name"
onChange={this.onChange}
/>
Then in our onChange
method, we can write:
onChange(event){
const { name, value } = event.target;
this.setState(prevState => {
prevState.fields[name] = value;
return {
fields: prevState.fields
};
});
};
We get the name
and value
properties from event.target
.
Then we call setState
with a callback to merge the new value with the existing state object.
Two React Components Communicating
There are a few scenarios where React components communicate.
The most common is parent-child communication.
For instance, we can write:
const Child = ({ onClick }) => (
<div onClick={() => onClick(42)}>
Click me
</div>
);
class Parent extends React.Component {
onClick(value){
console.log(value);
};
render() {
return (
<Child onClick={this.onClick}/>
)
}
}
We have the onClick
method in Parent
that we pass to the Child
component.
Then we get the onClick
from the props from the props
parameter.
Then we pass that to the onClick
callback where we call it with a value.
Then the console.log
will run.
If we want to communicate between components that have other relationships, we can use the Context API.
For instance, we can write:
const AppContext = React.createContext(null)
class App extends React.Component {
render() {
return (
<AppContext.Provider value={{ language: "en" }}>
<div>
<Foo>
<Bar>
<Baz />
</Bar>
</Foo>
</div>
</AppContext.Provider>
)
}
};
const Baz = () => (
<AppContext.Consumer>
{({language}) => <div>{language}</div>}
</AppContext.Consumer>
);
We call the React.createContext
to created the context.
Then we can use the AppContext.Provider
to pass the data into any components that are inside the AppContext.Provider
.
The value
prop has the data that we can access elsewhere.
Since our Baz
component is inside our context provider, we can use the AppContext.Consumer
to get the data and render it.
We have a callback inside it to get the language
from the object we passed into value
.
Conclusion
We can add multiple classes to a component with a template string or the classnames
package.
We can communicate between parent and child components directly.
Or we can use the context API to communicate between any component.
Various errors can be solved with quick fixes.