typescript SolidJS中的条件样式

r55awzrz  于 2022-12-14  发布在  TypeScript
关注(0)|答案(3)|浏览(123)

我在SolidJS中有一个组件,看起来像这样:

const MyComponent: Component = (params) => {
  // ...
  const [votes, setVotes] = createSignal(new Set());
  const toggle = (val: string) => {
    if (votes().has(val)) {
      let _votes = votes();
      _votes.delete(val);
      setVotes(_votes);
    } else {
      let _votes = votes();
      _votes.add(val);
      setVotes(_votes);
    }
  }

  return <>
    <For each={someArray()}>{(opt, i) =>
      <button 
        style={{
          color: `${ votes().has(opt) ? "blue" : "black"}`
        }} 
        onClick={() => { toggle(opt) } }
      >
        {opt()}
      </button>
    }</For>
  </>
}

我希望发生的是,按钮的样式将根据它(for循环中的opt)是否出现在votes集中而改变。
但是,这段代码不起作用,它不会在投票更新时更新。
votes变量按预期更新。
当我给予投票设置一个初始值时,会显示正确的样式(但之后不会更新)。
有什么解决办法让这一切顺利进行吗?

q3aa0525

q3aa05251#

@Nick说的似乎是正确的,请尝试将您的toggle方法更改为:

const toggle = (val: string) => {
    const _votes = votes();
    _votes.has(val) ? _votes.delete(val) : _votes.add(val);
    setVotes(new Set(_votes));
  }

Playground

lh80um4z

lh80um4z2#

在@solid-primitives/set中有一个React式Set原语,你可以直接将它用作state而不使用createSignal

carvr3hs

carvr3hs3#

该问题有一个可接受的答案,但实际问题是如何跟踪存储在集合中的值,而不是如何设置元素的样式。向下滚动以查看如何设置元素的样式。
Solid不跟踪Set,因为它依赖于代理API来跟踪对象的变化。有几种替代方法,但问题是,改变一个集合不会触发效果,除非我们用一个新的集合(如setVotes(new Set(votes().values()));)来替换它,因为集合是引用值。由于您在问题中传递的是相同的值,信号不会更新。

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

const App = () => {
  const [votes, setVotes] = createSignal(new Set());

  const castVote = () => {
    if (votes().has(4)) {
      votes().delete(4);
    } else {
      votes().add(4);
    }
    setVotes(new Set(votes().values()));
  };

  return (
    <>
      <button
        style={{
          color: votes().has(4) ? "blue" : "red",
        }}
        onClick={castVote}
      >
        Toggle
      </button>
    </>
  );
};
render(App, document.getElementById("app")!);

现在,更新元素的样式。
目前有两种方法可以定义元素上的内联样式:

  • 使用具有kebab-case索引键的对象。
  • 像处理HTML元素一样使用普通字符串。

您可以使用三元运算或其他条件表达式来有条件地创建值。

const App = () => {
  const [cond, setCond] = createSignal(true);

  const toggle = () => setCond(c => !c);

  return (
    <div onclick={toggle}>
      <span>conditon: {cond() ? 'true' : 'false'}</span>
      {` `}
      <span
        style={{ 'background-color': cond() ? 'red' : 'blue', color: 'white' }}
      >
        Using Object
      </span>
      {` `}
      <span
        style={`background-color: ${cond() ? 'red' : 'blue'}; color: white;`}
      >
        Using String
      </span>
    </div>
  );
};

render(App, document.querySelector('#app'));

相关问题