我正在尝试为solid-js 制作一个自定义“钩子”,它将从本地存储中检索状态。
import { Accessor, createSignal, Setter } from "solid-js";
export default function createLocalStorageSignal<T extends string>(key: string): [get: Accessor<T>, set: Setter<T>] {
const storage = window.localStorage;
const initialValue: T = JSON.parse(storage.getItem(key) ?? '{}').value;
const [value,setValue] = createSignal<T>(initialValue);
const newSetValue: Setter<T> = (newValue) => {
setValue(newValue);
storage.setItem(key, JSON.stringify({value: newValue}));
return newValue;
}
return [
value,
newSetValue
]
}
Run Code Online (Sandbox Code Playgroud)
但是我收到类型错误
Type '(newValue: any) => void' is not assignable to type 'Setter<T>'
Run Code Online (Sandbox Code Playgroud)
为什么不能推断 newValue 的类型?如果无法推断,我应该将其设置为什么?
编辑:
Setter<T>的完整类型是
type Setter<T> = undefined extends …Run Code Online (Sandbox Code Playgroud) 我如何在 SolidJS 中扩展一些现有 JSX 元素的属性,并创建我的自定义界面,就像ButtonProps下面给出的 React 示例中的界面一样。
import React from 'react';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
title: string;
showIcon: boolean;
}
const Button: React.FC<ButtonProps> = ({ title, showIcon, ...props }) => {
return (
<button {...props}>
{title}
{showIcon && <Icon/>}
</button>
);
};
Run Code Online (Sandbox Code Playgroud) 在solid-js中,当我们可以创建一个信号并导入它的getter/setter/甚至是来自存储全局存储类文件的记忆值时,使用context有什么好处?:
// ./store/myValue.js
export const [value, setValue] = createSignal('');
Run Code Online (Sandbox Code Playgroud)
据我了解,将其导入value多个组件中是完全可以的,并且在整个组件中都可以保持反应性。
我能想到的存储/全局的唯一用例是,如果您的状态变得如此复杂,那么您需要一种更加结构化的类似上下文的方法来提高可维护性、可读性等。
有没有办法将对象传递给第一个参数createResource?例如:我正在尝试以下操作,但它不起作用:
const [val] = createResource(props, req);
我还尝试了其他一些事情,包括以下内容:
const [val] = createResource(signal(), req);
const [val] = createResource(["foo","bar"], req);
const [val] = createResource(merged, req);
我相信 Solid 和 Svelte 的工作方式几乎相同,都使用反应图进行计算。
不同之处在于 Solid 使用函数以显式方式执行此操作,而 Svelte 执行相同的操作,但使用特殊的语法。
但它们在概念上和内部上几乎相同吗?
React的useState和Solid JS的createSignal有什么区别?
Solid 的信号比 React 的状态有优势吗?
import React, { useState } from "react";
function App() {
const [counter, setCounter] = useState(0);
return (
<div>
<p>{counter}</p>
<button onClick={() => setCounter((counter) => counter + 1)}>
Click Me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
import React, { useState } from "react";
function App() {
const [counter, setCounter] = useState(0);
return (
<div>
<p>{counter}</p>
<button onClick={() => setCounter((counter) => counter + 1)}>
Click Me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
哪一种在性能和心智模型方面更好?
我有一个createResource正在工作:
const fetchJokes = async (programmingOnly) => {
alert(programmingOnly);
return (await fetch(`https://official-joke-api.appspot.com/jokes/${programmingOnly?'programming/':''}ten`)).json();
}
//...
const [jokes, { mutate, refetch }] = createResource(programmingOnly(), fetchJokes);
Run Code Online (Sandbox Code Playgroud)
现在我想programmingOnly通过它的信号更改布尔值:
const [programmingOnly, setProgrammingOnly] = createSignal(true);
//...
Programming Only: <input type="checkbox" checked={programmingOnly()}
onInput={()=>{setProgrammingOnly(!programmingOnly());refetch();}}> </input>
Run Code Online (Sandbox Code Playgroud)
但这不起作用,警报会在后续尝试中触发,但未定义为 arg,并且数据没有任何反应。
SolidJS 解决这个问题的方法是什么?
我有一个父组件返回:
<List list={list()}>
{(item, index) => <div>{item}</div>}
</List>
Run Code Online (Sandbox Code Playgroud)
其中list是创建的信号。List是我返回的自定义组件:
<div>
<For each={list}>{children}</For>
</div>
Run Code Online (Sandbox Code Playgroud)
但每当list更新时,它都不会呈现。当我将For代码移至父组件时,它会进行渲染,那么将信号的值传递给子组件以使其在更新时不会重新渲染又是什么呢?
编辑:演示
import { render } from "solid-js/web";
import { createSignal, For } from "solid-js";
function Counter() {
const [list, setList] = createSignal([]);
const increment = () => setList([...list(), 1]);
return (
<>
<button type="button" onClick={increment}>
add
</button>
<p>broken list</p>
<List list={list()} />
<p>other list</p>
<For each={list()}>
{(item) => <p>{item}</p>}
</For>
</>
);
}
function List({list}) {
return …Run Code Online (Sandbox Code Playgroud) 在下面的例子中,如果我不这样做?对于 event.target.value,打字稿有错误Object is possibly null。与?我得到了错误Property 'value' does not exist on type 'EventTarget'。
我需要做什么才能使 onchange 的事件类型正确?
import { createSignal } from "solid-js";
export default function Cards() {
const [cellsWide, setCellsWide] = createSignal(0);
return (
<>
<div>
<select
name="cellsWide"
onChange={(e: Event) => {
console.log(e?.target?.value);
}}
>
<option value="5">5</option>
<option value="3">3</option>
</select>
</div>
<div>This is where cards goes - {cellsWide()}</div>
</>
);
Run Code Online (Sandbox Code Playgroud) 假设我有以下组件,我将如何迭代并渲染每个子组件以执行诸如用其他组件包装每个子组件之类的操作?
interface StuffProps {
children: `?`
}
function Stuff({ children }: StuffProps) {
// ?
}
Run Code Online (Sandbox Code Playgroud)
我尝试过设置children: JSX.Element然后执行<For each={children}> ... </For>,但它给了我一个打字稿错误。