아카이브

[Solid] Syntax | 12. On & Untrack 본문

Frontend/SolidJS

[Solid] Syntax | 12. On & Untrack

Rayi 2024. 7. 1. 10:41

on( )과 untrack( )은 특정 Signal또는 Store의 반응성을 제어하는데 사용하는 함수이며, 서로 반대의 기능을 수행합니다.

아래의 두 가지 예제는 Increment A 버튼을 누르면 변경된 A, B값이 출력되지만 Increment B 버튼을 누르면 변경된 값이 출력되지 않는 코드 입니다.

1. on()

특정 Signal & Store가 변경될 때의 반응성을 설정합니다.

 

모든 Signal & Store 에 대해 반응하는 effect와 달리, on은 특정 값에 대해서만 반응성을 설정한다는 차이가 있습니다.

 

on( ) 함수는 첫 번째 인자로 Signal & Store를 받으며, 두 번째 인자로 신호가 변경될 때 실행할 함수를 받습니다.

 

추가로 on은 defer 옵션을 제공하는데, 이를 사용하면 계산이 즉시 실행되지 않고 첫 번째 변경 시에만 실행되도록 할 수 있습니다.

import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";

const App = () => {
  const [a, setA] = createSignal(1);
  const [b, setB] = createSignal(1);

  // b는 반응성을 추적하지 않기 때문에, setB()가 실행될때는 effect가 실행되지 않습니다.
  // 단, a는 반응성을 처리하기 때문에, setA()가 실행되면 변경된 a, b값이 모두 출력됩니다.
  createEffect(on(a, (a) => {
    console.log(a, b());
  }, { defer: true }));
  // defer가 false이면 시작하자마자 console.log()가 실행됩니다.
  // defer가 true이면 시작할 때 console.log()가 실행되지 않으며, 버튼을 누를 때 처음 실행됩니다.
  
  return <>
    <button onClick={() => setA(a() + 1)}>Increment A</button>
    <button onClick={() => setB(b() + 1)}>Increment B</button>
  </>
};

render(App, document.getElementById("app"));

2. untrack()

내부에서 Signal & Store를 읽을 때 그에 대한 반응성을 만들지 않습니다.

 

untrack( ) 내에서 읽은 Signal & Store는 외부에서 그 값이 바뀌어도, 그 반응성에 영향을 받지 않습니다.

 

Signal & Store를 읽더라도 그 값에 의존성을 추가하지 않으므로, 특정 코드가 반응성을 따르지 않도록 할 때 사용됩니다.

 

단, untrack은 읽기 추적을 비활성화해도 쓰기는 영향을 미치지 않기 떄문에, 쓰기 작업은 여전히 추적됩니다.

import { render } from "solid-js/web";
import { createSignal, createEffect, untrack } from "solid-js";

const App = () => {
  const [a, setA] = createSignal(1);
  const [b, setB] = createSignal(1);

  // b는 반응성을 추적하지 않기 때문에, setB()가 실행되어도 effect가 실행되지 않습니다.
  // 단, a는 여전히 반응성을 처리하기 때문에, setA()가 실행되면 변경된 a, b값이 모두 출력됩니다.
  createEffect(() => {
    console.log(a(), untrack(b));
  });

  return <>
    <button onClick={() => setA(a() + 1)}>Increment A</button>
    <button onClick={() => setB(b() + 1)}>Increment B</button>
  </>
};

render(App, document.getElementById("app"));

 

728x90
Comments