모범 사례 및 패턴에 반응하여 코드 줄이기 - 3부



이것은 React 모범 사례에 대한 세 번째 기사입니다. 이전 기사를 읽지 않았다면 확인하십시오.







코드를 줄이기 위한 모범 사례와 패턴을 좀 더 살펴보겠습니다.




localStorage가 아닌 HTTP 쿠키에 토큰 저장


잘못된 코드:



const token = localStorage.getItem("token");
if (token) {
  axios.defaults.headers.common["Authorization"] = token;
}




좋은 코드:



import Cookies from "js-cookie"; //  use another library if you want

const token = Cookies.get("token");
if (token) {
  axios.defaults.headers.common["Authorization"] = token;
}




더 나은 코드:



No Code 😉


메모:
  • 쿠키는 동일한 도메인의 모든 사이트와 공유됩니다. 모든 요청에 ​​토큰을 전달할 필요가 없습니다. 백엔드가 프런트엔드와 동일한 도메인에 있지 않은 경우 두 번째 접근 방식을 사용해야 합니다.
  • JavaScript를 통해 쿠키 값(토큰)에 액세스하지 못하도록 하려면 HttpOnly 속성을 사용하십시오. 그러나 경로 액세스를 확인하려면 React 앱에 플래그가 필요합니다.




  • 인증 토큰 또는 기타 공통 헤더에 인터셉터 사용


    잘못된 코드:



    axios.get("/api", {
      headers: {
        ts: new Date().getTime(),
      },
    });
    




    좋은 코드:



    // only once
    axios.interceptors.request.use(
      (config) => {
        // Do something before request is sent
        config.headers["ts"] = new Date().getTime();
        return config;
      },
      (error) => {
        // Do something with request error
        return Promise.reject(error);
      }
    );
    
    // Component
    axios.get("/api");
    





    소품을 자식에게 전달하기 위해 context/redux를 사용하십시오.


    잘못된 코드:



    const auth = { name: "John", age: 30 };
    return (
      <Router>
        <Route path="/" element={<App auth={auth} />} />
        <Route path="/home" element={<Home auth={auth} />} />
      </Router>
    );
    




    좋은 코드:



    return (
      <Provider store={store}>
        <Router>
          <Route
            path="/"
            element={<App />}
          />
          <Route
            path="/home"
            element={<Home />}
          />
        </Router>
    );
    
    
    // Inside child component
    const { auth } = useContext(AuthContext); // For context
    const { auth } = useSelector((state) => state.auth); // For redux
    





    styled-components에 헬퍼 함수 사용


    나쁜 코드는 아니지만 px로 생각하면 읽기 어렵습니다.



    const Button = styled.button`
      margin: 1.31rem 1.43rem;
      padding: 1.25rem 1.5rem;
    `;
    




    px에서 rem으로의 변환을 위한 도우미 함수 만들기



    const toRem = (value) => `${value / 16}rem`;
    const Button = styled.button`
      margin: ${toRem(21)} ${toRem(23)};
      padding: ${toRem(20)} ${toRem(24)};
    `;
    





    입력 데이터 변경 공통 기능 사용


    잘못된 코드:



    const onNameChange = (e) => setName(e.target.value);
    const onEmailChange = (e) => setEmail(e.target.value);
    
    return (
      <form>
        <input type="text" name="name" onChange={onNameChange} />
        <input type="text" name="email" onChange={onEmailChange} />
      </form>
    );
    




    좋은 코드:



    const onInputChange = (e) => {
      const { name, value } = e.target;
      setFormData((prevState) => ({
        ...prevState,
        [name]: value,
      }));
    };
    
    return (
      <form>
        <input type="text" name="name" onChange={onInputChange} />
        <input type="text" name="email" onChange={onInputChange} />
      </form>
    );
    





    지연 로딩에 교차 관찰자 사용


    잘못된 코드:



    element.addEventListener("scroll", function (e) {
      // do something
    });
    




    좋은 코드:



    const useScroll = (ele, options = {}): boolean => {
      const [isIntersecting, setIsIntersecting] = useState(false);
      useEffect(() => {
        const cb = (entry) => setIsIntersecting(() => entry.isIntersecting);
        const callback: IntersectionObserverCallback = (entries) => entries.forEach(cb);
        const observer = new IntersectionObserver(callback, options);
        if (ele) observer.observe(ele);
        return (): void => ele && observer.unobserve(ele);
      }, [ele]);
      return isIntersecting;
    };
    
    
    // Component
    const ref = useRef<any>();
    const isIntersecting = useScroll(ref?.current);
    
    useEffect(() => {
      if (isIntersecting) {
        // call an API
      }
    }, [isIntersecting]);
    
    





    인증 및 개인 경로에 HOC 사용


    잘못된 코드:



    const Component = () => {
      if (!isAuthenticated()) {
        return <Redirect to="/login" />;
      }
      return <div></div>;
    };
    




    좋은 코드:



    const withAuth = (Component) => {
      return (props) => {
        if (!isAuthenticated()) {
          return <Redirect to="/login" />;
        }
        return <Component {...props} />;
      };
    };
    
    // Route
    <Route path="/home" component={withAuth(Home)} />;
    
    // Component
    const Component = (props) => <div></div>;
    export default withAuth(Component);
    





    경로 객체 배열을 사용하여 경로 정의


    일반적인 접근 방식:



    return (
      <Router>
        <Route path="/" element={<App />} />
        <Route path="/about" element={<About />} />
        <Route path="/topics" element={<Topics />} />
      </Router>
    );
    




    좋은 코드:



    const routes = [
      {
        path: "/",
        role: ["ADMIN"],
        element: React.lazy(() => import("../pages/App")),
        children: [
          {
            path: "/child",
            element: React.lazy(() => import("../pages/Child")),
          },
        ],
      },
      {
        path: "/about",
        role: [],
        element: React.lazy(() => import("../pages/About")),
      },
      {
        path: "/topics",
        role: ["User"],
        element: React.lazy(() => import("../pages/Topics")),
      },
    ];
    
    const createRoute = ({ element, children, role, ...route }) => {
      const Component = role.length > 0 ? withAuth(element) : element;
      return (
        <Route key={route.path} {...route} element={<Component />}>
          {children && children.map(createRoute)}
        </Route>
      );
    };
    
    return <Routes>{routes.map(createRoute)}</Routes>;
    


    참고: 이렇게 하려면 더 많은 코드가 필요하지만 더 유연합니다. 더 많은 HOC를 사용하려면 createRoute만 업데이트하면 됩니다.




    Typescript 사용


    Typescript 😀를 사용하지 않아도 잘못된 것은 없지만 더 나은 코드를 작성하는 데 도움이 됩니다.



    npx create-react-app my-app --template typescript
    





    서식에 더 예쁜 eslint 사용



    npm install -D eslint prettier
    npx eslint --init
    




    참조: Eslint setup , Prettier setup

    😥 전체 단계를 추가하지 않고 짧고 간단하게 유지하고 싶습니다. 어려운 점 있으면 댓글 남겨주세요.




    사전 커밋 후크를 사용하여 eslint를 더 예쁘게 실행



    npx mrm@2 lint-staged // This will install and configure pre-commit hook
    
    // This script will be created at the root of your project
    .husky/pre-commit
    
    // Package.json
    "lint-staged": {
      "src/**/*.{js,ts,jsx,tsx}": [
        "npm run lint",
        "npm run prettier",
        "npm run unit-test",
        "git add"
      ]
    }
    


    메모:
  • 커밋 시 더 예쁘고 eslint를 실행하도록 구성을 업데이트할 수 있습니다. 프로젝트 package.json에서 명령을 추가하거나 제거할 수 있습니다.
  • 이를 위해 CI 및 CD를 설정하는 것이 좋습니다. 누군가 사전 커밋 후크를 주석 처리하고 코드를 git에 푸시할 수 있습니다.




  • 더 나은 개발을 위해 vscode 확장 사용


    Auto Close Tag , Auto Rename Tag , CodeMetrics , CSS Peek , ES7+ React/Redux/React-Native snippets , Eslint , GitLens , Import Cost , Prettier

    참고: 코드 복잡성 확장(CodeMetrics)을 시도해야 합니다. 코드의 복잡성을 보여줌으로써 더 나은 코드를 작성하는 데 도움이 됩니다.




    읽어주셔서 감사합니다 😊

    질문이나 추가 사항이 있습니까? 댓글을 남겨주세요.


    당신이하지 않은 경우 읽어야합니다













    자세한 내용은 .


    Github , , , Medium , Stackblitz에서 나를 잡아라.

    좋은 웹페이지 즐겨찾기