Common mistakes of juniors using React By Zoranin Tutorials - February 14, 2022 Comments: 0 Views: 531 This article highlights some of the mistakes React developers make early in their careers.Direct DOM manipulationThis kind of error is especially common among developers who have just migrated from jQuery.Have you written such code?import React from "react"; export class Menu extends React.Component { componentDidMount() { if (window.innerWidth < 500) { const menu = document.querySelector(".menu"); menu.classList.add("mobile"); } } render() { return <div className="menu">{this.props.children}</div>; } }What is the problem?In React, we must avoid direct interactions with the DOM. Instead of getting a reference to the DOM node and adding a class to it directly, you should change the state in the component itself, based on which the class will be added to the element.What is so bad about direct DOM manipulation?Any web application is actually built on the state and its management. There is a direct relationship between software complexity and the state that describes it. If your application combines DOM and React state, then the complexity of maintaining it will grow very quickly.Possible Solutionimport React from "react"; export class Test extends React.Component { state = { isMobile: false }; componentDidMount() { if (window.innerWidth < 500) { this.setState({ isMobile: true }); } } render() { return ( <div className={this.state.isMobile ? "mobile" : ""}> {this.props.children} </div> ); } }Let's take a look at how we're using React's state to update an attribute classNameon our component, and as a result, we got rid of the document.querySelector. Fine!Don't follow resourcesNewcomers to development often write code like this when they work with events. Take, for example, a simple React component that does… something when the user presses spacebar.import React from "react"; export class CaptureSpace extends React.Component { componentDidMount() { document.body.addEventListener("keydown", event => { if (event.keyCode === 32) { // do something when user hits spacebar } }); } render() { return ( // ); } }Notice how we added an event listener but didn't take care to remove it at the end?This can lead to memory leaks and subtle issues in the future. The best solution is to remove subscribers before our component is removed from the DOM.Let's take a look at the solution below:import React from "react"; export class CaptureSpace extends React.Component { componentDidMount() { document.body.addEventListener("keydown", this.captureSpace); } componentWillUnmount() { document.body.removeEventListener("keydown", this.captureSpace); } captureSpace = event => { if (event.keyCode === 32) { // do something when user hits spacebar } }; render() { return ( // ); } }Refusal of tests (or insufficient number of them)If I was given a dollar for every project I reviewed where the only test was the default one in create-react-app, I wouldn't be writing this article. And, probably, he was sipping a daiquiri somewhere on the beach now.What is it about testing that scares the juniors so much? I think the reason lies in the non-triviality of testing components, especially given their constant development and growth in complexity. I often see junior programmers write unit tests for certain pure functions, but fail when they need to write an integration test for an entire component.Maybe the stubs are confusing them? Or do they struggle with what should be tested and what should not?Let's take a look at the component I just wrote. This is a very simple login form where the user must enter their username and password. When the latter confirms the entered information, we make an API call and, if the answer is yes, we direct the client to another page.import React from "react"; import axios from "axios"; export const LoginForm = props => { const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); return ( <form onSubmit={async event => { event.preventDefault(); const result = await axios.post("https://reqres.in/api/login", { email, password }); if (result.data.token) { window.localStorage.setItem("token", result.data.token); window.location.replace("/home"); } }} > <div> <label htmlFor="email">Email</label> <input id="email" onChange={event => setEmail(event.target.value)} value={email} /> </div> <div> <label htmlFor="password">Password</label> <input id="password" type="password" onChange={event => setPassword(event.target.value)} value={password} /> </div> <button type="submit">Submit</button> </form> ); };So how do you test this form?First of all, let's take a look at how our user will interact with it.The user enters their data.The user clicks on the confirmation button.The user is redirected to the "home" page.This is all we need to test.Below I wrote one of the test cases for this component. Can you suggest any other scenarios that would be useful to test?import React from "react"; import { LoginForm } from "./Login"; import axios from "axios"; import { render } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; jest.mock("axios"); describe("LoginForm", () => { describe("when a user types in a correct email and password", () => { it("should redirect to home page", async () => { const rendered = render(<LoginForm />); const emailInput = rendered.getByLabelText("Email"); await userEvent.type(emailInput, "[email protected]"); const passwordInput = rendered.getByLabelText("Password"); await userEvent.type(passwordInput, "1234"); delete window.location; window.location = { replace: jest.fn() }; const data = { data: { token: "fake-token" } }; axios.post.mockImplementationOnce(() => Promise.resolve(data)); userEvent.click(rendered.getByText("Submit")); expect(window.location.replace).toHaveBeenCalledWith("/home"); }); }); });Misunderstanding WebpackSome of the junior developers I worked with knew how to use but didn't understand how Webpack worked. They only used it with the main codebase of the project and believed that everything else “works just because”. They didn't dig deeper, figure out exactly how the CSS and ES6 they write is transformed and combined into what is ultimately used by the client browser.I recommend that every React developer take the time to build a simple template project. Instead of relying on create-react-app and NextJS every time, understand how modern jаvascript build tools work together. This will improve your understanding of your work and, as a result, make you a more efficient developer, especially when solving build problems.
How to Implement Complex Navigation in iOS Apps for iPhone Every app, unless it's a single-page app, must have navigation that allows users to move between February 14, 2022 Tutorials
How to develop your first app with React Native I want to talk a little about what React Native is, why it is important and popular now, and January 24, 2022 Tutorials
How to quickly write an Android game with Unity At the present time, anyone can become a successful mobile game or application developer without January 9, 2022 Tutorials