typescript 如何简单地改变信号中的数组

huus2vyu  于 2022-12-05  发布在  TypeScript
关注(0)|答案(2)|浏览(153)

这是一个工作示例,但有一个问题。我想在信号内拼接一个现有数组,并返回它以查看其更新。但它不起作用。我如何简单地在信号内改变数组?我不想创建新数组,只是一个简单的拼接。文档中没有关于改变数组的示例。

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

function HelloWorld() {
  let [a, setA] = createSignal([])

  setTimeout(() => 
  setA(a => {
    a.splice(0, 0, 'hello')
    // this logs as requested if I uncomment this
    //return ['hello']
    return a
  }))

  createEffect(() => {
    console.log(a())
  })
  return <div>Hello World!</div>;
}

render(() => <HelloWorld />, document.getElementById('app'))
nbysray5

nbysray51#

实体教程strongly recommends immutability
Solid强烈推荐使用浅层不可变模式来更新状态。通过分离读和写,我们可以更好地控制系统的React性,而不会在通过组件层时丢失对代理的更改跟踪。
一个不可改变的方式来完成你想要的可能看起来像这样:

setA(a => ['hello', ...a])

但是,如果您决定必须改变信号,您可以指定Solid如何确定信号是否在createSignal的选项对象中更新。默认情况下,使用===运算符通过 * 引用相等性 * 比较信号变化。您可以通过将equals设置为false,告诉Solid在调用setter后 * 总是 * 重新运行依赖项:

let [a, setA] = createSignal([], { equals: false });

或者,您可以传递一个函数,该函数接受信号的previousnext值并返回boolean

let [a, setA] = createSignal([], { equals: (prev, next) => {
  if (/* dependents should run */) {
    return false;
  }
  // dependents shouldn't run
  return true;
} });
yhived7q

yhived7q2#

警告:我是Solid.js和Javascript/Typescript的新手。我下面所做的可能是一个非常糟糕的主意。
我遇到了同样的问题,并解决了以下问题。它似乎是可行的。基本上将值(例如,一个非常大的数组)保存在一个轻量级的 Package 类型中。重新创建 Package 类型,而不是重新创建数组。下面的函数createSignalMutable返回一个getter函数,它返回未 Package 的值,以及一个updater函数,它更新未 Package 的值。

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

type ThinWrapper<T> = {
  internal: T;
};

function createSignalMutable<T>(value: T) {
  let [getter, setter] = createSignal<ThinWrapper<T>>({ internal: value });

  let getUnwrapped = () => getter().internal;

  let updateUnwrapped = (mutator: (value: T) => void) =>
    setter((oldWrapped: ThinWrapper<T>) => {
      mutator(oldWrapped.internal);
      let newWrapped: ThinWrapper<T> = { internal: value };
      return newWrapped;
    });

  return [getUnwrapped, updateUnwrapped];
}

let initialValue: number[] = [];
let [numbers, updateNumbers] = createSignalMutable(initialValue);

createEffect(() => {
  console.log("Array length is now ", [...numbers()].length);
});

updateNumbers((val) => val.push(1));
updateNumbers((val) => val.push(2));

这将打印

Array length is now  0
Array length is now  1
Array length is now  2

操场链接here

相关问题