typescript - kör createEffect endast för specifik setSignal som utlöses vid användarinteraktion


Jag försöker bygga en textredigerare, där _cursor är positionen för markören. setInterval 4000 sekunder är som att användaren flyttar markören. I vilket fall vill jag köra en effekt.

Men ofta ställer jag markören som en bieffekt internt, till exempel när viss text raderas eller läggs till eller vid en ångra-operation. I det fallet vill jag inte köra createEffect i exemplet.

Så hur gör jag för att createEffect bara ska köras för andra setInterval 4000 och inte för första setInterval.

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

function Counter() {
   const [_cursor, _setCursor] = createSignal(100)
  

  createEffect(on(_cursor, (v, p) => {
     if (p && v < p) {
        console.log('reset')
     }
  }))

  setInterval(() => {
     _setCursor(_cursor() - 1)
  }, 500)

  setInterval(() => {
     _setCursor(_cursor() - 1)
  }, 4000)


  return (<>
     <span>{_cursor()}</span>
    </>)
}

render(() => <Counter />, document.getElementById("app"));

Svar #1

Du kan ställa in en annan flagga och använda dess värde för att kontrollera genomförandet av effekten:

  const [flag, setFlag] = createSignal(true);

  createEffect(on(_cursor, (v, p) => {
    if (flag()) return;
    if (p && v < p) {
      console.log('reset')
    }
  }));

Observera att effekten inte följer flaggan:

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

function Counter() {
  const [cursor, setCursor] = createSignal(100);
  const [flag, setFlag] = createSignal(true);

  createEffect(on(cursor, (v, p) => {
    if (flag()) return;
    if (p && v < p) {
      console.log('reset')
    }
  }))

  setInterval(() => {
    setCursor(cursor() - 1);
  }, 500);

  setInterval(() => {
    setCursor(cursor() - 1)
  }, 4000);

  // This is for demonstrating the logic
  setInterval(() => setFlag(!flag()), 1000);

  return (
    <>
      <span>{cursor()}</span>
    </>
  )
}

render(() => <Counter />, document.getElementById("app"));