장독깨기
5k
2022-02-14 17:51:16
13
4604

react vs jquery vs javascript


jquery 가 일부 사람들에게 천덕꾸러기로 너무 조롱을 당하고 있는게 눈꼴 시러워서, :)

react, jquery, javascript 로 각각 구현하여 비교해 봤습니다.


아래는 리액트 튜터리얼에 있는 예제입니다.

설명은  https://ko.reactjs.org/tutorial/tutorial.html 에서,

동작하는 건 https://codepen.io/gaearon/pen/gWWZgR?editors=0010   에서 볼 수 있습니다.

<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js" integrity="sha512-qlzIeUtTg7eBpmEaS12NZgxz52YYZVF5myj89mjJEesBd/oE9UPsYOX2QAXzvOAZYEvQohKdcY8zKE02ifXDmA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js" integrity="sha512-9jGNr5Piwe8nzLLYTk8QrEMPfjGU0px80GYzKZUxi7lmCfrBjtyCc1V5kkS5vxVwwIB7Qpzc7UxLiQxfAN30dw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js" integrity="sha512-kp7YHLxuJDJcOzStgd6vtpxr4ZU9kjn77e6dBsivSz+pUuAuMlE2UTdKB7jjsWT84qbS8kdCWHPETnP/ctrFsA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<script type="text/babel">

function Square(props) {
    return (
        <button className="square" onClick={() =>  props.onClick()}>
            {props.value}
        </button>
    )
}

class Board extends React.Component {
    renderSquare(i) {
        return  <Square value={this.props.squares[i]}
                        onClick={() => this.props.onClick(i)}
                />;
    }

    render() {
        return (
            <div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

class Game extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            history: [{
                squares: Array(9).fill(null),
            }],
            stepNumber: 0,
            xIsNext: true,
        };
    }

    calculateWinner(squares) {
        const lines = [
            [0, 1, 2],
            [3, 4, 5],
            [6, 7, 8],
            [0, 3, 6],
            [1, 4, 7],
            [2, 5, 8],
            [0, 4, 8],
            [2, 4, 6],
        ];
        for (let i = 0; i < lines.length; i++) {
            const [a, b, c] = lines[i];
            if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
                return squares[a];
            }
        }
        return null;
    }

    handleClick(i) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();

        if (this.calculateWinner(squares) || squares[i]) return;
    
        squares[i] = this.state.xIsNext ? 'X' : 'O';
        this.setState({
            history: history.concat([{
                squares: squares
            }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext
        });
    }

    jumpTo(step) {
        this.setState({
            stepNumber: step,
            xIsNext: (step % 2) === 0,
        });
    }

    render() {
        const history = this.state.history;
        const current = history[this.state.stepNumber];
        const winner = this.calculateWinner(current.squares);

        const moves = history.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';
            return (
                <li key={move}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            );
        });

        let status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
        if (winner) status = 'Winner: ' + winner;

        return (
            <div className="game">
                <div className="game-board">
                    <Board squares={current.squares} onClick={(i) => this.handleClick(i)} />
                </div>
                <div className="game-info">
                    <div>{status}</div>
                    <ol>{moves}</ol>
                </div>
            </div>
        );
    }
}

function App() {
    return (
        <Game />
    );
}

documentReady(() => {
    ReactDOM.render(
        <React.StrictMode>
            <App />
        </React.StrictMode>,
        document.getElementById('root')
    );
});
</script>

<body>
    <div id="root"></div>
</body>
</html>


같은 기능을 jquery 로 구현한 코드입니다.

<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js" integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<script>

class Game {
    squareClass = "";
    jumpClass = "";
    status = null;
    moves = null;

    xIsNext = true;
    stepNumber= 0;
    history = [{ squares: Array(9).fill(null), }];

    constructor(squareClass, jumpClass, status, moves) {
        this.squareClass = squareClass;
        this.jumpClass = jumpClass;
        this.status = status;
        this.moves = moves;
        this.eventListeners();
    }

    eventListeners() {
        $(this.squareClass).click( e => {
            this.squareClick(e);
        });
        /*
        document.querySelectorAll(this.squareClass).forEach( element => element.addEventListener("click", e => {
            this.squareClick(e);
        }));
        */

        $(document).on("click", this.jumpClass, e => {
            this.jumpClick(e);
        });
        /*
        document.addEventListener("click", e => {
            if(e.target.className == this.jumpClass.substring(1))
                this.jumpClick(e);
        });
        */
    }

    calculateWinner(squares) {
        const lines = [
            [0, 1, 2],
            [3, 4, 5],
            [6, 7, 8],
            [0, 3, 6],
            [1, 4, 7],
            [2, 5, 8],
            [0, 4, 8],
            [2, 4, 6],
        ];
        for (let i = 0; i < lines.length; i++) {
            const [a, b, c] = lines[i];
            if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
                return squares[a];
            }
        }
        return null;
    }

    squareClick(e) {
        const history = this.history.slice(0, this.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();

        let i = $(e.target).attr("num");
        //let i = e.target.getAttribute("num");
        if (this.calculateWinner(squares) || squares[i]) return;

        squares[i] = this.xIsNext ? 'X' : 'O';

        this.history = history.concat([{ squares: squares }]);
        this.stepNumber = history.length;
        this.xIsNext = !this.xIsNext;

        $(e.target).html(squares[i]);
        //e.target.innerHTML = squares[i];

        this.updateStatus();
    }

    jumpClick(e) {
        const key = Number.parseInt($(e.target).closest("li").attr("key"));
        //const key = Number.parseInt(e.target.closest("li").getAttribute("key"));
        this.stepNumber = key;
        this.xIsNext = (key%2) == 0
        this.updateSquares();
    }

    updateStatus() {
        const history = this.history;
        const current = history[this.stepNumber];
        const winner = this.calculateWinner(current.squares);

        const moves = history.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';

            return Handlebars.compile([
                "<li key={{move}}>",
                "   <button class='jump'>{{desc}}</button>",
                "</li>"
                ].join(""))
                ({"move": move, "desc": desc});
        });

        let status = 'Next player: ' + (this.xIsNext ? 'X' : 'O');
        if (winner) status = 'Winner: ' + winner;

        $(this.status).html(status);
        //this.status.innerHTML = status;

        $(this.moves).html(moves);
        //this.moves.innerHTML = moves.join("");
    }

    updateSquares() {
        const current = this.history[this.stepNumber];
        current.squares.forEach((value,i) => {
            $(this.squareClass).siblings('[num=' + i + ']').html(value);
            //document.querySelector(this.squareClass + '[num="' + i + '"]').innerHTML = value;
        });
    }
}

$(document).ready(() => {
    new Game(".square", ".jump", $("#status"), $("#moves"));
});
/*
document.addEventListener("DOMContentLoaded", () => {
    new Game(".square", ".jump", document.querySelector("#status"), document.querySelector("#moves"));
});
*/

</script>

<body>
    <div id="root">
        <div class="game">
            <div class="game-board">
                <div>
                    <div class="board-row">
                         <button class="square" num=0></button>
                         <button class="square" num=1></button>
                         <button class="square" num=2></button>
                    </div>
                    <div class="board-row">
                        <button class="square" num=3></button>
                        <button class="square" num=4></button>
                        <button class="square" num=5></button>
                    </div>
                    <div class="board-row">
                        <button class="square" num=6></button>
                        <button class="square" num=7></button>
                        <button class="square" num=8></button>
                    </div>
                </div>
            </div>
            <div class="game-info">
                <div id="status">Next player: X</div>
                <ol id="moves">
                    <li key=0><button class='jump'>Go to game start</button></li>
                </ol>
            </div>
        </div>
    </div>
</body>
</html>


같은 기능을 javascript 로는 ... 별도로 구현해 볼 필요가 없습니다.

위 코드에서 주석 처리해 둔 걸 해제하면 javascript 로 구현한 게 됩니다.

별 다른 차이점이 있나요? 보면 알겠지만 1대1로 모두 대체 가능합니다.

간편한 걸 선호하면 jquery 를 쓰면 될 일이고, jquery 꼴 보기 싫으면 javascript 만 쓰면 될 일 입니다.

jquery 는 언어가 아니라  dom 을 간편하게 다룰 수 있는 라이브러리 입니다.

도대체 라이브러리를 언어와 비교해서 등불이 됐다가 안 됐다가 하는게 말이 된다고 생각하세요.

참 답답한 일 입니다. :)


그럼 react 와 비교해 보겠습니다.

react 는 프레임웍이죠. 구조도 다르고 처리 방식도 흐름도 다릅니다.

비교해서 보니 어떤가요. react 를 적용한게 더 나아 보이시나요.

이건 사람마다 호불호가 있을 수 있고, 상황에 따라 또 다를 수 있다 생각합니다.

제가 생각하는 기준으로는,

SPA 로 개발해야 할 상황이 아니라면,

react 를 적용할 필요성을 전혀 못 느끼며, 되려 훨신 더 불편해 보입니다.

불편한 이유를 굳이 얘기할 필요는 없어 보이니 언급은 않겠습니다.


중요한건 저 처럼 생각하는 이들이 많이 있을 수 있고,

또는 다른 여러 이유로 react 나 vue 를 적용하지 않을 수 있습니다.

무슨 얘기냐면, 막상 취업했는데 jquery 로 개발하는 경우가 많이 있을 수 있다는 얘깁니다.

이럴 때 너무 실망하거나 커리어 꼬일까 너무 걱정할 필요가 없다는 말씀 드리고 싶습니다.

jquery, react 이런 거 말고도 배우고 익혀야 할 건 너무 많고, 시간 또한 충분히 있습니다.

차차 실력 키워 나가면서, 이래 저래 이직도 하면서, 커리어 잘 쌓으면 될 일 입니다. 


5
  • 댓글 13

  • 후하하핫
    9k
    2022-02-15 04:49:51

    당장 어떤 프레임워크나 어떤 언어를 쓰는게 커보일지 몰라도, 10년 후 미래를 생각하면 어떤걸 쓰는 곳이든 가장 빨리 성장할 수 있는 곳에서 열심히 일했던게 남는 거라는 사실을 신입 및 저년차들에게 이해 시키기 참 어려운 것 같습니다. 페북은 php로 만들었는데 (나중에 Hack이라는 언어를 새로 만들긴 했지만) 서비스가 크고, 마크 주커버그가 부자가 되는데 그 사실이 어떤 영향도 주지 않았는데 말이죠.

  • xml개발자
    3k
    2022-02-15 11:28:48


    애초에 목적이 다른 건데

    진짜 제이쿼리랑 리액트 비교하는 놈이 제일 무식한거죠...

  • kenu
    61k
    2022-02-15 23:04:16

    막상 취업했는데 svn 쓰는 곳도 여전히 많습니다.

  • 하하121
    614
    2022-02-19 05:04:00

    듣기에만 좋은 이상향이에요. 팩트는 제이쿼리만 주구창창 다룬사람은 리액트 시니어로 안뽑는다는 겁니다. 제이쿼리가 적합한 프로젝트는 그냥 딱 회사 소개 홈페이지 정도겠져.  현시점의 제이쿼리는 벡엔드 개발자가 Fe 할 사람없고 사용자 편의성 신경안쓰는 FE 난이도가 낮을 프로젝트때 그냥 적당히 때우기 좋은 용도 정도입니다. 

  • 장독깨기
    5k
    2022-02-19 16:33:17 작성 2022-02-19 16:49:19 수정됨

    하하121

    절 굉장히 싫어하는 분이 시네요. :)

    리액트 시니어를 안뽑는다는게 팩트일지 어떨지는 잘 모르겠지만, 어쨌든 한 번 보겠습니다.

    만약 어떤 회사가 리액트 시니어를 뽑는다면, 이런 회사는 너무 뻔해서 전 안 갑니다.

    기껏 시니어를 뽑는데 리액트를 기준으로 삼는 다는게 웬 말입니까. 

    훨씬 더 많은 실력과 경험을 요구해야 하며 그게 당연합니다.

    둘째. react 로 하는 프로젝트는 전부 jquery 로 할 수 있으며 그 동안 그렇게 해왔습니다.

    단, spa 일 경우 jquery 로 할 수는 있겠지만 너무 비 효율적이며 이때는 react를 도입하는게 좋습니다.

    근데 spa 로 해야 할 경우가 얼마나 있을지 모르겠군요.

    spa 로 할 필요가 없는걸 굳이 spa를 고집한다면 이것도 현명한 생각은 아닙니다.

    마지막으로, 사용자 편의성은 react, jquery 이런 거랑 전혀 관련이 없으며,

    역시 react 로 하는건 모두 jquery 로 할 수 있습니다.

    쉽게 편하게 할 수 있는걸 어렵게 하는거 만큼 미련한 짓도 없습니다.


    가급적 사실을 여러 관점으로 객관화시켜 정확하게 알수록 좋습니다.

    그래야 대비를 할 수 있습니다. :)

  • 하하121
    614
    2022-02-20 07:26:39

    안 싫어하는데요, 원래 안맞는 말있으면 반박 댓글 답니다. 제 기록 봐보시면 될거같고요

    더 많은 실력과 경험을 요구하는 FE에 투자를 많이하는 회사는 애초에 쌩 제이쿼리로 작업을 안합니다;;;

    "별도의 프레임워크 없이 쌩 제이쿼리로 서비스를 만든다 = FE는 화면만 보이면 된다" 입니다. 그래서 제가 이상이 아니라 현실적으로 보라고 얘기한거고요.  OKKY 게시판 정도의 서비스면 애초에 시니어 프론트 두지도 않습니다. 

    시니어를 뽑는다는건 그만큼 사용자편의성에 신경을 많이 쓰고 FE 난이도가 높다는건데 카카오/토스 정도의 서비스에서 쌩 제이쿼리로 작업하는 회사있음 하나만 얘기해보세요. 


  • 장독깨기
    5k
    2022-02-20 11:18:09 작성 2022-02-20 11:59:32 수정됨

    하하121

    안 싫어한다니 다행입니다. :)

    음... 쌩 제이쿼리가 뭐죠. 왜 쌩 이란 단어를 쓰는지 궁금하네요. 본 글에 사례로 든건 쌩 제이쿼리인가요?

    사용자 편의성도 무슨 상관관계가 있길래 자꾸 얘기하는지 모르겠습니다. 혹 설명 가능할까요?

    프런트 난이도 부분도 어떤 관점에서 얘기하는지 모르겠습니다.

    UI 편집기 같은 일반적이지 않은 건 난이도가 좀 있습니다.

    이런 걸 얘기하시나요. 근데 이런 건 프레임웍과 전혀 관계없으며,

    일일이 얘기하진 못하지만, 해당 회사 개발자들이 못하겠다 해서

    제가 외주받아 구현한 것들이 제법 됩니다. 자바스크립트와 제이쿼리로요.

    마지막으로, 카카오톡 이런 모바일 앱 서비스를 리액트로 만들었다 하시는건가요?

    이건 말이 안되죠. 물론 당연히 제이쿼리도 아닙니다.

    아님 설마 카카오/토스 회사 홈페이지를 얘기하시는건가요?

    이건 서비스가 아니고 그냥 단순 회사소개입니다. 여기에 사용자편의성, 난이도 이런게 있을수가 없죠.

    뭘 애기하는지 모르겠으니 어떤 회사를 얘기해야 할 지도 모르겠습니다.

    리액트 같은 프레임웍을 적용하지 않은 모든 회사들이라 얘기하면 될려나요. 네이버 어떤가요. :)


    아, 그리고 현실은 이렇습니다.

    네카라쿠배... 이런 좋은 회사나 시리즈A 이상 스타트업을 합쳐도 소수이며 들어가기가 만만치 않습니다.

    대부분은 SI 나 외주사업, 초소규모 허접 스타트업에 몸 담고 있는거죠.

    좋은 회사에 가기 위한 경쟁력은 리액트, 제이쿼리 이런게 아닙니다.

    뭐가 중요한지 깊이 생각해 볼 일 입니다.


  • 하하121
    614
    2022-02-21 03:46:05

    네이버 당장 채용공고만 보더라도 떡하니 SPA가 있는데 안쓴다는 말은 왜 나온건지 모르겠습니다만.... 그냥 당장 잡코리아에 Jquery 검색해 보세요. 그냥 거의 다 영세기업에서 벡엔드 개발자가 JSP같은 거 이용해서 적당히 view 구현하는 공고들입니다. 이런데서 일하다가 네카라쿠배 FE 시니어로 전직하는게 현실성이 있어 보이시나요? 사용자 편의성을 얘기하는 이유는 UI 난이도가 올라가면 컴포넌트 단위로 개발하는 SPA가 더 효율적이여서 말하는겁니다. 물론 제이쿼리도 템플릿 엔진쓰면 "가능"은 합니다. 

    그냥 대놓고 얘기해서 현 시점에 제이쿼리로 신규프로젝트를 구축하면서 FE 개발자를 따로 뽑으며 초봉 4천이상 주는 회사? 대한민국에 있지도 않습니다.  

  • 장독깨기
    5k
    2022-02-21 04:25:54

    그만 하겠습니다. :)

  • hellox
    213
    2022-02-23 10:04:26

    저도 jquery 가 너무 천대 받고 있다고 생각합니다.

    실제로 현장에서는 jquery가 편한것도 맞는거 같습니다. 보통은 서버사이드 렌더링이 주이고 몇가지 기능이 ajax 처리할 때 사용하기 편하다고 생각합니다.

    하지만 react 나 vue 기술의 기술발전 방향은 분명합니다. 렌더링 자동화와 가상돔 사용입니다. 개발자들은 데이터가 변한 다음 렌더링을 신경을 덜 쓰게 됩니다. 렌더링 속도를 보장하기 위해서, 가상 돔도 사용합니다. 리얼 돔 구조를 서치해서 변경점을 찾기는 속도가 느려지기 때문이죠.

    제 짧은 의견으로는 이 기술발전 방향을 바뀌지는 않을거 같습니다.

    jquery도 좋지만, 가능한 react 나 vue를 사용해서 변화에 적응해 나가면 좋지 않을까 생각합니다.

  • 장독깨기
    5k
    2022-02-23 16:50:54 작성 2022-02-23 16:55:56 수정됨

    hellox

    네. 시대 변화에 따라 적응해 나가는거 동의하고, 잘 할 수록 좋습니다.

    당연한 얘기고 이걸 부정할 사람은 없을거라 봅니다. 저 또한 마찬가지구요.


    계산기를 서비스한다고 해보겠습니다.

    1. 디자인을 이쁘게 합니다.

    2. 퍼블리싱을 합니다.

    3. 동적인 부분을 처리합니다. 숫자나 연산자를 입력 처리하는거죠.

    4. 식을 해석하고 계산을 합니다.

    자바스크립트, 제이쿼리, 리액트 이런 거는 2,3 번과 관련된 얘기 입니다.

    전 4번이 중요하다고 말씀드리고 싶은 겁니다.

    본 글의 사례는 3X3 보드 게임 입니다.

    이걸 9X9, 19X19 로 변경을 하면 2, 3번에 해당하는건 변경하기 쉽습니다.

    핵심 로직은 calculateWinner 이 부분이죠. 4번에 해당하는 겁니다. 

    프로젝트 하는데 2,3 번 때문에 망가지지 않습니다. 늘 4번에 해당하는게 문제가 되는거죠.

    백앤드 부분도 마찬가지입니다. JPA로 하면 근사하고 mybatis 로 하면 구려. 이런게 아니란 거죠.

    자바스크립트가 발전했으니 제이쿼리 구려 이렇게 조롱할 일이 아니란 겁니다.

    프로젝트 상황에 따라 얼마든지 제이쿼리도 리액트도 쓸 수 있습니다.

    2,3 번에 해당하는건 그 기술이 뭐든 누구나 다 하게 되어 있습니다. 시간이 문제일 뿐이죠.

    중요한건 4번이고 이 부분을 잘해야 경쟁력도 생기고 좋은 회사도 갈 수 있습니다.

    그니까, 신입으로 취업 했는데 최신 기술을 사용하지 않는다고 해서

    너무 실망하거나 걱정할 필요 없다는 점, 배워야 할 건 충분히 많다는 점 말씀 드리고 싶은 겁니다.


  • 매일공부합니당
    79
    2022-02-26 15:32:24

    바닐라자바스크립트랑 jqeury로 해도 되지만 

    큰 프로젝트의경우 조잡한 코드로 인해  협업이 힘들지않나요?

    php도 그렇고 jquery도 그렇고 다 좋은데 레거시한 코드를 보면 건들고 싶지 않는경우가 많은 것 같습니다.

  • 장독깨기
    5k
    2022-02-28 20:39:42

    조잡한 코드는 프로젝트 규모나 언어, 라이브러리 등 과는 상관 관계가 별로 없습니다.

    해당 코드를 작성한 팀이나 개발자의 역량이 문제가 되겠죠.

    혹 조잡한 코드의 정의에 개인의 주관적인 취향이 반영된거라면 이건 좀 생각해 보는게 좋겠습니다.

    가급적 긍정적이고 객관적인 관점을 유지하는게 실력 향상에 도움이 될거라 생각합니다.

  • 로그인을 하시면 댓글을 등록할 수 있습니다.