-
[221207] setState의 함수형 업데이트방식 / URI vs URL vs URN / query parameter, query string, path variableTIL 2022. 12. 7. 14:54
setState의 함수형 업데이트방식
아래의 일반 사용법의 경우 setNumber(number + 1) 를 3번 호출했지만 number가 1씩 증가한다. 그 이유는 setState의 비동기적 특성 때문이다. 리액트가 효율적으로 렌더링하기 위해 여러 개의 상태 값 변경 요청을 batch(일괄 처리) 처리하기 때문이다.
구체적으로는
setState가 여러번 호출되면 인자로 전달된 각 객체를 추출하여 단일 객체로 merge 하는데 이런 과정은 '오브젝트 컴포지션' 이라고 한다 . batch 처리의 이유는 당연히 성능 이슈 때문이다. 리렌더링을 발생하는 setState가 일어날 때마다 리렌더링이 일어난다면 얼마나 많은 렌더링이 일어나겠는가? 그렇다면 setState를 사용하기가 두려워질 수도 있을 듯하다.
// src/App.js import { useState } from "react"; const App = () => { const [number, setNumber] = useState(0); return ( <div> {/* 버튼을 누르면 1씩 플러스된다. */} <div>{number}</div> <button onClick={() => { setNumber(number + 1); // 첫번째 줄 setNumber(number + 1); // 두번쨰 줄 setNumber(number + 1); // 세번째 줄 }} > 버튼 </button> </div> ); } export default App;
하지만 setState 를 동기적으로 사용하는 방법은 없을까? 다음과 같이 함수형업데이트를 사용하는 것이다. 함수를 인자로 전달받은 setState는 원하는 시점의 상태를 가지고 업데이트를 한다. 객체가 아닌 함수형 setState가 호출되면 merge 할 객체가 없기 때문에 호출된 순서대로 함수를 큐에 넣는다. 그 후에 큐의 각 함수를 호출하여 함수형 setState의 이전 상태를 전달하여 상태를 업데이트 하는 것이다.
// src/App.js import { useState } from "react"; const App = () => { const [number, setNumber] = useState(0); return ( <div> {/* 버튼을 누르면 3씩 플러스 된다. */} <div>{number}</div> <button onClick={() => { setNumber((previousState) => previousState + 1); setNumber((previousState) => previousState + 1); setNumber((previousState) => previousState + 1); }} > 버튼 </button> </div> ); } export default App;
그런데 왜 onClick안에 바로 함수를 넣지 않고 한번 더 빈 함수를 감싼다음에 넣는 걸까...?
onClick={}에서 중괄호 안에는 무조건 클릭이 되었을 때 실행할 함수를 넣어야한다. 그러므로 onClick={setState}와 같이 실행할 함수를 바로 넣어줘야한다. 그런데 setState()이나 setState(0)과 같이 함수를 실행해버린 형태나 함수 안에 매개변수를 넣어야해서 함수를 실행한 형태가 되어버리면 더 이상 실행할 함수명 자체가 아니기 때문에 문제가 생긴다. 그래서 onClick={() => {setState(0)}}의 형태로 익명함수를 먼저 넣고 그 안에 함수를 실행하도록 코드를 짜야하는 것이다. 위의 경우 실행할 코드가 하나이므로 중괄호를 생략하여 onClick={() => setState(0)}와 같이 작성해도 가능하다. 만약 onClick={setState(0)}의 형태로 작성한다면 중괄호 내부가 함수명이 아니므로 즉각 함수를 실행시켜 작동시키게 된다.
URI vs URL vs URN
URI는 Uniform Resource Identifier, 통합 자원 식별자의 줄임말이다. 브라우저의 검색창을 클릭하면 나타나는 주소가 URI이다. (URI는 인터넷의 자원을 식별할 수 있는 문자열을 의미한다. 그 중 URL이라는, URN이라는 하위 개념을 만들어서 특별히 어떤 표준을 지켜서 자원을 식별하는 것이다.) 인터넷에 있는 자원을 나타내는 유일한 주소이다.
URL은 Uniform Resource Locator의 줄임말이다. URL은 네트워크 상에서 웹 페이지, 이미지, 동영상 등의 파일이 위치한 정보를 나타낸다. URN은 콘텐츠를 이루는 한 리소스에 대해, 그 리소스의 위치에 영향 받지 않는 유일무이한 이름 역할을 한다. 이 위치 독립적인 URN은 리소스를 여기저기로 옮기더라도 문제없이 동작한다.
URN은 (Uniform Resource Name)의 줄임말이다. URN은 URI의 표준 포맷 중 하나로, 이름으로 리소스를 특정하는 URI이다. http와 같은 프로토콜을 제외하고 리소스의 name을 가리키는데 사용된다. URN은 리소스를 영구적이고 유일하게 식별할 수 있는 URI이다. URN에는 리소스 접근방법과, 웹 상의 위치가 표기되지 않는다. URN은 리소스 자체에 부여된 영구적이고 유일한 이름이고 변하지 않는다. 실제 자원을 찾기 위해서는 URN을 URL로 변환하여 이용한다.
URL은 어떻게 리소스를 얻을 것이고 어디에서 가져와야하는지 명시하는 URI이다. URN은 리소스를 어떻게 접근할 것인지 명시하지 않고 경로와 리소스 자체를 특정하는 것을 목표로하는 URI이다.
URN은 아직 채택되지 않아, 접할 기회가 없었을 것이다. URN은 URL의 한계로 인해 착수되었다. URL의 한계란,
URL은 주소이지 실제 이름이 아니다. 이 뜻은 특정 시점에 어떤 것이 위치한 곳을 알려준다는 것이다. 예를 들어, 구글 검색에 노출된 http://mygumi.tistory.com/19 링크가 있다. 본인은 주소를 바꾸고 싶어 http://mygumi.tistory.com/test/19 로URL을 바꾸었다. 다른 사람이 노출된 검색 콘텐츠에 접근 시 노출된 페이지는 찾을 수 없게 된다. 이러한 단점으로 리소스가 옮겨지면 해당 URL을 더는 사용할 수 없다는 것이다. 그리고 그 시점 기존 URL이 가지고 있던 객체를 찾을 방법이 없어진다.
이런 문제를 예방할 수 있는 이상적인 방법은, 객체의 위치와 상관없이, 그 객체를 가리키는 실제 객체의 이름을 사용하는 것이다. 그렇게 되면, 위치가 바뀌더라도 리소스의 위치를 찾을 수 있게 된다. (URL 또한 PURL을 사용하면 URN 기능을 제공할 수 있다)
query parameter, query string, path variable 이란 각각 무엇인가?
URL파라미터(쿼리 파라미터)란 위 URL 중에서 물음표 ‘?’ 이후 문자열을 뜻합니다. URL 파라미터는 ‘웹 서버에 저장된 프로그램을 웹 브라우저로 전달하는 것’이라고 이해할 수 있습니다. [파라미터 명]=[파라미터 값]이 한 세트 로 작동하고, 파라미터가 여러 개 일 때는 마찬가지로 위에 빨갛게 마킹해 둔 것처럼 ‘&’로 이어줍니다.
/users?**id**=123 # 아이디가 123인 사용자를 가져온다.
이를 통해 서버로 부터 id 변수를 얻을 수 있다. 이것이 Query String이 동작하는 방식이다. 하지만 데이터를 넘기는 방법 중의 하나로 Path Variable도 사용할 수 있다.Path Variable은 다음과 같이 사용한다.(URL 파라미터와 쿼리 파라미터는 같은 의미이며 쿼리 파라미터와 쿼리 스트링도 매우 비슷한 의미임. 구분이 힘들다)
/users/123 # 아이디가 123인 사용자를 가져온다.
'TIL' 카테고리의 다른 글
[230106] 게시판 구조 설계 (0) 2023.01.07 [221219] 좋아요 기능 구현 요구 사항 (0) 2022.12.19 [221207] css hover와 비동기처리 (1) 2022.12.07 [221206] Todo 리스트 페이지를 리덕스와 라우터 사용하여 만들기 (0) 2022.12.06 [221130] 데이터 바인딩 / SPA (1) 2022.11.30