React.js에서 선언적과 명령 적의 차이점은 무엇입니까?


102

최근 저는 Facebook JavaScript 라이브러리 React.js를 사용하는 기능과 방법에 대해 많은 연구를했습니다. 종종 자바 스크립트 세계에서 두 개의 프로그래밍 스타일의 나머지의 차이 말할 때 declarativeimperative했나요된다.

둘의 차이점은 무엇입니까?


23
latentflip.com/imperative-vs-declarative Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
rickyduck

4
Tyler McGinnis는 좋은 예와 함께 이것에 대한 긴 기사 를 썼습니다 .
Ian Dunn

왜 주석으로 긴 대답을 추가 ..?
알렉스

1
위의 링크는 정확하지만 링크에 포함 된 후행 슬래시 (404)의 원인 latentflip.com/imperative-vs-declarative
제임스 유

답변:


173

react가 가지고있는 것과 같은 선언적 스타일을 사용하면 "It should look like this"라고 말하여 애플리케이션의 흐름과 상태를 제어 할 수 있습니다. 명령형 스타일은이를 바꾸고 "이것이 당신이해야 할 일"이라고 말함으로써 당신의 애플리케이션을 제어 할 수있게합니다.

선언적의 이점은 상태를 나타내는 구현 세부 사항에 얽매이지 않는다는 것입니다. 애플리케이션보기를 일관되게 유지하는 조직 구성 요소를 위임하므로 상태에 대해서만 걱정하면됩니다.

프레임 워크에 대한 일종의 은유 인 집사가 있다고 상상해보십시오. 그리고 당신은 저녁을 만들고 싶습니다. 명령형 세계에서는 저녁 식사를 만드는 방법을 단계별로 알려줄 것입니다. 다음 지침을 제공해야합니다.

Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

선언적 세계에서는 원하는 것을 간단히 설명 할 수 있습니다.

I want dinner with chicken.

집사가 닭고기를 만드는 방법을 모르면 선언적 스타일로 작업 할 수 없습니다. Backbone이 특정 작업을 수행하기 위해 자신을 변형하는 방법을 모르는 것처럼, 해당 작업을 수행하도록 지시 할 수 없습니다. 예를 들어 React는 "닭을 만드는 방법을 알고"있기 때문에 선언적 일 수 있습니다. 주방과 인터페이스하는 방법 만 아는 백본과 비교.

상태를 설명 할 수 있으면 버그의 표면적이 크게 줄어들어 이점이 있습니다. 반면에 상태를 구현하는 방법을 위임하거나 추상화하기 때문에 상황이 발생 하는 방식대한 유연성이 떨어질 수 있습니다.


81

"좋아요"버튼과 같은 간단한 UI 구성 요소를 상상해보십시오. 탭하면 이전에 회색 이었으면 파란색으로, 이전에 파란색 이었으면 회색으로 바뀝니다.

이를 수행하는 필수 방법은 다음과 같습니다.

if( user.likes() ) {
    if( hasBlue() ) {
        removeBlue();
        addGrey();
    } else {
        removeGrey();
        addBlue();
    }
}

기본적으로 현재 화면에있는 내용을 확인하고 이전 상태의 변경 사항을 취소하는 것을 포함하여 현재 상태로 다시 그리는 데 필요한 모든 변경 사항을 처리해야합니다. 실제 시나리오에서 이것이 얼마나 복잡한 지 상상할 수 있습니다.

반대로 선언적 접근 방식은 다음과 같습니다.

if( this.state.liked ) {
    return <blueLike />;
} else {
    return <greyLike />;
}

선언적 접근 방식은 관심사를 분리하기 때문에이 부분에서는 UI가 개별 상태로 표시되는 방식 만 처리하면되므로 이해하기 훨씬 간단합니다.


22

이것은 큰 비유입니다.

* 긴급 대응 : 주차장 북쪽 출구로 나와 좌회전 Bangerter Highway 출구가 나올 때까지 I-15 남쪽으로갑니다. Ikea에가는 것처럼 출구에서 우회전하십시오. 직진하여 첫 번째 신호등에서 우회전하십시오. 다음 신호등을 통과 한 후 다음 좌회전하십시오. 우리 집은 # 298입니다.

선언적 응답 : 내 주소는 298 West Immutable Alley, Draper Utah 84020 *입니다.

https://tylermcginnis.com/imperative-vs-declarative-programming/


19

React (선언적)와 JQuery (명령어)를 비교하여 차이점을 보여주는 것이 가장 좋습니다.

React에서는 render()이전 UI 상태에서 새 UI 상태로 전환하는 방법에 대해 걱정하지 않고 메서드 에서 UI의 최종 상태 만 설명하면됩니다 . 예 :

render() {
  const { price, volume } = this.state;
  const totalPrice = price * volume;

  return (
    <div>
      <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... />
      <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... />
      <Label value={totalPrice} ... />
      ...
    </div>
  )
}

반면에 JQuery를 사용하려면 UI 상태를 명령 적으로 전환해야합니다 (예 : 레이블 요소 선택 및 해당 텍스트 및 CSS 업데이트).

updatePrice(price) {
  $("#price-label").val(price);
  $("#price-label").toggleClass('expansive', price > 100);
  $("#price-label").toggleClass('cheap', price < 100);

  // also remember to update UI depending on price 
  updateTotalPrice();
  ... 
}

updateVolume(volume) {
  $("#volume-label").val(volume);
  $("#volume-label").toggleClass('high', volume > 1000);
  $("#volume-label").toggleClass('low', volume < 1000);
  
  // also remember to update UI depending on volume
  updateTotalPrice();
  ... 
}

updateTotalPrice() {
  const totalPrice = price * volume;
  $("#total-price-label").val(totalPrice);
  ...
}

실제 시나리오에서는 업데이트 할 UI 요소와 그 속성 (예 : CSS 스타일 및 이벤트 리스너) 등이 더 많이있을 것입니다. JQuery를 사용하여 반드시이 작업을 수행하면 복잡하고 지루해집니다. UI의 일부를 업데이트하는 것을 잊거나 오래된 이벤트 핸들러를 제거하는 것을 잊기 쉽습니다 (메모리 누수 또는 핸들러가 여러 번 실행되는 원인). 여기에서 버그가 발생합니다. 즉, UI 상태와 모델 상태가 동조.

모델 상태를 업데이트하기 만하면되고 React는 UI와 모델 상태를 동기화 상태로 유지해야하기 때문에 React의 선언적 접근 방식에서는 동기화되지 않은 상태가 발생하지 않습니다.

  • 후크 아래에서 React는 명령형 코드를 사용하여 변경된 모든 DOM 요소를 업데이트합니다.

선언적 프로그래밍과 명령 적 프로그래밍의 차이점은 무엇입니까?에 대한 내 대답을 읽을 수도 있습니다 . .

추신 : 위의 jQuery 예제에서 모든 DOM 조작을 updateAll()메서드에 넣고 모델 상태가 변경 될 때마다 호출하면 UI가 동기화되지 않을 것이라고 생각할 수 있습니다. 당신이 맞고 이것은 React가하는 일 입니다. 유일한 차이점은 jQuery updateAll()가 불필요한 DOM 조작을 많이 유발 한다는 점 입니다.하지만 React는 Virtual DOM Diffing Algorithm을 사용하여 변경된 DOM 요소 만 업데이트 합니다.


8

명령형 코드는 JavaScript가 각 단계를 수행하는 방법을 지시합니다. 선언적 코드를 사용하여 원하는 작업을 JavaScript에 알리고 JavaScript가 단계를 수행하도록합니다.

React는 우리가 원하는 코드를 작성하고 React가 선언 된 코드를 가져와 원하는 결과를 얻기 위해 모든 JavaScript / DOM 단계를 수행하기 때문에 선언적입니다.


5

명령형 세계에서 실제 유사점은 맥주 바에 들어가 바텐더에게 다음과 같은 지시를 내리는 것입니다.

-선반에서 유리 잔 가져 오기

-초안 앞에 유리를 놓습니다.

-유리가 가득 찰 때까지 손잡이를 아래로 당깁니다

-유리를 건네주세요.

선언적인 세계에서는 대신 "맥주, 제발"이라고 말하면됩니다.

맥주를 요청하는 선언적 접근 방식은 바텐더가 맥주를 제공하는 방법을 알고 있다고 가정하고 이것이 선언적 프로그래밍 작동 방식의 중요한 측면입니다.

선언적 프로그래밍에서 개발자는 달성하고자하는 것만 설명하고 작동하도록 모든 단계를 나열 할 필요가 없습니다.

React가 선언적 접근 방식을 제공한다는 사실은 사용하기 쉽고 결과적으로 결과 코드가 단순하여 종종 버그가 적고 유지 관리 가능성이 높아집니다.

React는 선언적 패러다임을 따르기 때문에 DOM과 상호 작용하는 방법을 말할 필요가 없습니다. 화면에서보고 싶은 것을 선언하고 React가 작업을 수행합니다.



0
  • 선언적은 모든보기를 제어 할 수 있습니다. (상태 관리와 같은)
  • Imperative는 뷰 주변을 제어 할 수 있습니다. (예 : $ (this))

0

비유로 시작하겠습니다. 두 대의 차가 있고 두 대의 차에는 차 내부의 온도가 상온 ~ 72 ° F가되기를 원합니다. 첫 번째 (오래된) 자동차에는 온도를 제어하는 ​​두 개의 노브 (온도를 제어하는 ​​노브 1 개와 공기 흐름을 제어하는 ​​노브 1 개)가 있습니다. 너무 뜨거워지면 온도를 낮추고 공기 흐름을 변경하기 위해 첫 번째 손잡이를 조정해야하며 너무 추우면 그 반대입니다. 이것은 필수 작업입니다! 손잡이를 직접 관리해야합니다. 두 번째 (신형) 차에서 온도를 설정 / 선언 할 수 있습니다. 즉, 온도를 조정하기 위해 손잡이를 조작 할 필요가 없음을 의미합니다. 온도를 72 ° F로 선언 / 설정하면 내 차가 그 상태에 도달하기 위해 필수 작업을 수행한다는 것을 알고 있습니다.

React는 동일합니다. 마크 업 / 템플릿과 stat를 선언하면 React는 DOM을 앱과 동기화 상태로 유지하기위한 명령적인 작업을 수행합니다.

<button onClick={activateTeleporter}>Activate Teleporter</button>

.addEventListener()이벤트 처리를 설정하는 데 사용 하는 대신 원하는 것을 선언합니다. 버튼을 클릭하면 activateTeleporter기능 이 실행 됩니다.


0

선언적 vs 명령 적

선언적 프로그래밍은 친구에게 집을 칠 해달라고 요청하는 것과 같습니다. 당신은 그들이 그것을 어떻게 청소하는지, 그들이 페인트하는 데 어떤 색을 사용하는지, 그들이 그것을 완성하기 위해 얼마나 많은 자원을 사용했는지는 신경 쓰지 않습니다.

//Declarative For Searching element from an array
  array.find(item)

선언적의 반대는 필수적입니다. 명령형 접근 방식의 일반적인 예는 집을 칠하기 위해해야 ​​할 일을 친구에게 정확히 말한 것입니다.

  • 세제로 집을 씻으십시오.
  • Narolac 페인트 또는 아시아 페인트 사용
  • 지붕을 녹색으로 칠하십시오.
  • 3 인 계약 등

// Imperative Algo

def imperative_search(array, item)
  for i in array do
    if i == item
      return item
    end
  end
  return false
end

0

이것은 지금까지 나의 이해입니다.

선언적 코드 (거의?)는 항상 본질적으로 더 필수적인 코드 위의 추상화 계층입니다.

React를 사용하면 DOM과 직접 상호 작용하는 명령형 코드 (예 : diffing 알고리즘 ) 위에 추상화 계층 인 선언적 코드를 작성할 수 있습니다 . 명령형 코드를 작성해야하는 경우 (즉, DOM과 직접 상호 작용) React는 Refs를 이스케이프 해치로 제공합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.