brunch

You can make anything
by writing

C.S.Lewis

by 이종우 Peter Lee Mar 20. 2020

[번역] 주니어 React 개발자들의
실수들

그리고 실수들을 피하는 방법

https://medium.com/frontend-digest/mistakes-junior-react-developers-make-c546b1af187d

주니어 리 액트 개발자의 실수들

그리고 그들을 피하는 방법


프란체스코 Gallarotti Unsplash


경력을 쌓으면서 많은 주니어 개발자들과 함께 일하고 멘토링을 해왔습니다. 나는 그들의 강점과 약점을 보았고, 그들이 성장하고 더 완전한 개발자가되는 것을 보았습니다.


며칠 전에 새로운 React 개발자가 작성한 코드를 검토하고 있었습니다. 다음은 그들이 저지른 실수와 경험이 적은 개발자가 본 몇 가지 함정입니다.


이 게시물은 판단하거나 조롱하기위한 것이 아닙니다. 우리 모두는 주니어 개발자로 시작하여 많은 실수를 저질렀습니다. 500 명의 실제 고객에게 테스트 이메일을 보냈을 때처럼. 그러나 나는 포기했다..


1. 직접적인 DOM 조작


이런 종류의 일은 새로운 개발자, 특히 이전에 jQuery를 사용해 본 개발자에게 매우 일반적입니다.


전에 이런 코드를 작성해 본 적이 있습니까?


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>; 
  } 
}


무엇이 문제인가요? 


React에서 우리는 직접적인 돔 조작을 피해야합니다. dom 요소에 액세스하고 클래스를 추가하는 대신 React 컴포넌트 내부의 상태를 유지하고 해당 상태를 사용하여 클래스를 컴포넌트에 추가해야합니다.


직접 돔 조작에있어 무엇이 잘못 되었습니까?


웹 응용 프로그램 만들기는 응용 프로그램 상태 관리에 관한 것입니다. 응용 프로그램이 커질수록 상태가 더 크고 복잡해집니다. 응용 프로그램이 DOM 내부와 React 내부의 상태를 혼합하면 추론하기가 어렵고 테스트하기가 어렵고 디버그하기가 더 어려워집니다.


가능한 해결책


import 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> 
    ); 
  } 
}


컴포넌트의 className을 업데이트하기 위해 React 상태를 어떻게 사용하고 있는지 확인하고 document.querySelector  사용법을 제거했습니다  .


좋습니다! 


추천!

생수 필요하신 분만 클릭 상품 클릭!

2. 자신을 정리하는 것을 잊어 버림


새로운 개발자는 종종 이벤트 작업을 시작할 때 이런 종류의 코드를 작성합니다. 예를 들어 사용자가 스페이스 바를 칠 때 수행하는 간단한 React 구성 요소를 예로 들어 보겠습니다.



import React from "react";

export class CaptureSpace extends  CaptureSpaces React.Component 확장 { 

  componentDidMount () { 
    document.body.addEventListener ( "keydown", event => { 
        if (event.keyCode === 32) { 
          // 사용자가 스페이스 바를 칠 때 무언가를 수행 
        } 
    }); 
  } render () { 
    return ( 
       // 
    ); 
  } 
}


이벤트 리스너를 어떻게 추가했지만 나중에 제거하지 않았습니까? 이로 인해 메모리 누수가 발생할 수 있으며 문제를 디버그하기가 어렵습니다. 컴포넌트를 마운트 해제하기 전에 이벤트 리스너를 제거하는 것이 가장 좋습니다.


아래 해결책을 확인하십시오.


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 (

       //

    );

  }

}



3. 테스트하지 않음 (또는 테스트하지 않음)


create-react-app의 기본 테스트 사례가 유일한 테스트인지 검토 한 모든 코딩 문제에 대해 1 달러가 있다면이 기사를 쓰지 않을 것입니다. 나는 아마 어딘가에 해변에서 'daiquiris' 를 마시고있을 것이다.


주니어 개발자들을 겁나게하는 테스트는 무엇입니까? 구성 요소 또는 응용 프로그램이 복잡해질수록 테스트 작성 작업이 더 어려워 진다고 생각합니다. 주니어 개발자들이 특정 순수 함수에 대한 단위 테스트를 작성하지만 전체 구성 요소에 대한 통합 테스트를 작성하지 못하는 경우가 종종 있습니다.


그들을 어쩌면 Mocking  Trips 합니까? 아니면 무엇을 테스트해야하는지 알아내는 데 어려움이 있습니까?


방금 쓴 구성 요소를 살펴 보겠습니다. 아마 몇 번 그런 것을 썼을 것입니다. 사용자가 사용자 이름과 비밀번호를 입력하는 간단한 로그인 양식입니다. 양식이 제출되면 API 호출이 수행되고 응답이 긍정적이면 사용자를 다른 페이지로 리디렉션합니다.


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>

  );

};



이 로그인 양식을 어떻게 테스트합니까?


먼저 사용자가이 구성 요소와 상호 작용하는 방법을 살펴 보겠습니다. 사용자 흐름을 적어 봅시다.  


사용자는 자신의 사용자 이름과 비밀번호를 입력합니다

사용자가 제출 버튼을 클릭합니다

사용자는 "홈"페이지로 리디렉션됩니다.


이것이 우리가 테스트해야 할 것입니다.


아래에서는이 구성 요소에 대한 테스트 사례를 작성했습니다. 유용한 다른 것들을 생각할 수 있습니까?


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, "john@gmail.com");

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");

    });

  });

});


4. Webpack을 이해하지 못한다


내가 함께 작업 한 후배 개발자 중 몇 명은 Webpack 사용 방법을 이해하고 있습니다. 그들은 제공된 코드베이스로 작업하고 모든 것이 작동한다고 가정합니다. 그들은 자신이 작성한 CSS와 ES6가 어떻게 변환되고 번들로 묶여서 사용자 브라우저에 들어가는 지 알아 내지 않습니다.


모든 React 개발자가 시간을내어 자체 상용구 프로젝트를 설정하는 것이 좋습니다. create-react-app 및 NextJS에 항상 의존하는 대신, 최신 JavaScript 빌드 도구가 함께 작동하는 방법을 알아 봅니다. 작업에 대한 이해도를 높이고 빌드 문제를 디버깅하는 데 도움이됩니다.      


당신이 주니어 일 때 저지른 다른 실수 나 주니어가 저지른 실수를 생각할 수 있습니까? 의견에서 그들에 대해 듣고 싶습니다!



매거진의 이전글 [번역]Flutter+Firebase noteapp 1
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari