Categories
React Tips

React Tips — Fix Common Errors, Multiple Classes, and Context API

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *