首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在solid-js中只听一个对象的特定值?

如何在solid-js中只听一个对象的特定值?
EN

Stack Overflow用户
提问于 2022-08-22 03:56:55
回答 2查看 67关注 0票数 3
代码语言:javascript
复制
const App: Component = () => {
  const [obj, setObj] = createSignal({
    name: "John",
    age: 30,
  })

  createEffect(
    on(
      () => obj().name,
      (value) => {
        console.log("name", value)
      }
    )
  )
return ()=>(<button onClick={()=> setObj(obj=> ({ ...obj, age: obj.age + 1}))}>+</button>)
}

当我更改age时,createEffect也会被触发,我只想监听name,类似于Vue3中的watch

代码语言:javascript
复制
function setup(){
  const obj = reactive({
    name: "John",
    age: 30,
  })
  watch(()=> obj.name,(value)=>{ console.log("name", value) })
}

有什么好主意吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-27 18:10:30

信号是提供单向数据流的原子值,这意味着通过设置新值来更新信号。即使传递相同的属性,也将设置一个新对象,因为在JavaScript中通过引用来比较对象,从而触发更新。

也就是说,有多种方法或方法来跟踪存储在信号中的对象的单个属性。

使用商店的

  1. createStore在内部使用代理,并提供跟踪单个属性的方法。您可以使用produce,一种用于本地化突变的加密API,因此只更新某些属性。

  1. 您可以创建一个回忆录信号来跟踪对象上的单个属性。在这里,只更改年龄重新运行效果,但是更新名称没有任何效果:

代码语言:javascript
复制
import { render } from "solid-js/web";
import { createSignal, createMemo, createEffect } from "solid-js";

function App() {
  const [person, setPerson] = createSignal({ name: "John Doe", age: 20 });
  const handleClick = () => setPerson({ name: "Jenny Doe", age: 20 });

  const age = createMemo(() => person().age);

  createEffect(() => {
    console.log("Age is updated", age());
  });

  return (
    <button type="button" onClick={handleClick}>
      {JSON.stringify(person())}
    </button>
  );
}

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

solid-js

  1. 使用on实用程序

代码语言:javascript
复制
import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";
import { createStore } from "solid-js/store";

function App() {
  const [person, setPerson] = createStore({ name: 'John Doe', age: 30 });
  const increment = () => setPerson(p => ({ ...p, age: p.age + 1 }));

  createEffect(on(() => person.name, () => {
    console.log('Tracking name');
  }));

  createEffect(on(() => person.age, () => {
    console.log('Tracking age');
  }));

  return (
    <button type="button" onClick={increment}>
      {person.name} {person.age}
    </button>
  );
}

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

此方法也适用于信号:

代码语言:javascript
复制
import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";

function App() {
  const [person, setPerson] = createSignal({ name: 'John Doe', age: 30 });
  const increment = () => setPerson(p => ({ ...p, age: p.age + 1 }));

  createEffect(on(() => person.name, () => {
    console.log('Tracking name');
  }));

  createEffect(on(() => person().age, () => {
    console.log('Tracking age');
  }));

  return (
    <button type="button" onClick={increment}>
      {person().name} {person().age}
    </button>
  );
}

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

您可以在createSignal:中使用参数

代码语言:javascript
复制
import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";

function App() {
  const [person, setPerson] = createSignal(
    { name: "John Doe", age: 20 },
    { equals: (prev, next) => prev.age === next.age }
  );

  const handleClick = () => setPerson({ name: "Jenny Doe", age: 20 });

  createEffect(() => {
    console.log("Age is updated", person());
  });

  return (
    <button type="button" onClick={handleClick}>
      {JSON.stringify(person())}
    </button>
  );
}

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

这些都是开箱即用的解决方案,但由于Solid非常灵活,而且非常宽松,如果您愿意,可以实现您自己的逻辑。

票数 2
EN

Stack Overflow用户

发布于 2022-09-10 03:08:06

SolidJS将不会跟踪信号对象的单个属性。

此外,每当一个值在销毁时发生变化时,您都会覆盖该对象(也就是。{...obj,}

如果希望createEffect跟踪单个属性,请尝试createStore

下面是用createStore而不是createSignal编写的示例

代码语言:javascript
复制
import {createStore} from 'solid-js/store'; // <- This is very important

const App: Component = () => {
  const [obj, setObj] = createStore({
    name: "John",
    age: 30,
  })

  createEffect(() => console.log(obj.name));

  return (<button onClick={setObject('age', obj.age + 1)}>+</button>)
  )
}

如果您运行这个示例,您将看到console.log(obj.name)只运行一次,这是因为solid-js在将它们保存在createStore上时会跟踪它们的各个属性。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73440069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档