我在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>
</>
}我想要发生的是,按钮的样式将根据votes集合中的轮式( for循环中的votes)发生变化。
但是,此代码不起作用。当选票更新时,它不会更新。
选票变量确实会按预期更新。
当我给选票设置一个初始值时,就会显示正确的样式(但之后不会更新)。
有什么办法可以解决这个问题吗?
发布于 2022-05-19 05:15:10
在Set中有一个反应性的createSignal原语,您可以在不使用createSignal的情况下直接使用它作为状态。这可能会简化你的事情。
发布于 2022-05-19 01:13:51
@Nick所说的似乎是正确的,请尝试将您的toggle方法更改为:
const toggle = (val: string) => {
const _votes = votes();
_votes.has(val) ? _votes.delete(val) : _votes.add(val);
setVotes(new Set(_votes));
}发布于 2022-05-22 16:28:36
这个问题有一个公认的答案,但实际问题是如何跟踪存储在集合中的值,而不是如何对元素进行样式设置。向下滚动查看如何设置元素的样式。
Solid不跟踪开箱即出的集合,因为它依赖于代理来跟踪对象。有几个备选方案,但问题是变异一个集合不会触发效果,除非我们用一个新的集合(如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")!);现在,更新元素的样式。目前,有两种方法可以在元素上定义内联样式:
可以使用三元操作或其他条件表达式有条件地创建值。
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'));https://stackoverflow.com/questions/72297265
复制相似问题