组件是一个函数,取得一些道具并呈现一个视图。在这些道具中,您可能有一些状态元素。当您进行多页水疗中心时,您会在每个新页面上重建组件。您可能需要使用全球商店在它们之间共享状态。对此的有用模式是上下文。您也可以通过参数化函数组件来做到这一点:
(context) => (props) => [HTML like stuff]
您可以沿着道路(例如主题),有用的功能来传递所有可能需要的东西...
有了一些框架,您可以在组件之外声明状态。使用SolidJS
,您可以使用createSignal
声明状态元素;它可以封装在组件中,也可以在其外部声明。您可以利用此“上下文”:如果您需要在组件之间共享它,则可以在上下文级别上声明。
// context.js
import {createSignal} from from "solid-js";
const [bool, setBool] = createSignal(false);
const context = {
bool, setBool,
theme: {...},
...
}
在下面的示例中,我们从上下文中获得了状态。
const comp1 = (ctx) => {
const {bool, setBool, theme} = ctx;
return const Comp1 = (props) =>
(
<p>The state value is: {bool() ? "true" : "false"}</p>
<button onClick={()=> setBool(v => !v}>Toggle</button>
{props?.children}
)
}
[...]
import context from "./context";
const Comp1 = comp1(context)
<Comp1>Hi</Comp1>
导航到另一个组件时,您会导入状态并每次导航回到此组件时具有反应性值。
const comp2 = (ctx) => {
const {bool} = ctx;
return () =>
(
<div>
<p>Comp1 changed the state: {bool()}</p>
</div>
)
}
[...]
import context from "./context";
const Comp2 = comp2(context)
<Comp2/>
我们可以具有从组件中设置数据的异步函数,我们希望在其他地方使用结果。当您想使用SOLIDJS运行异步调用时,在SolidJS文档中指定了应该使用createResource
。然后,如果需要更新状态,则应避免使用createEffect
,因为这用于突变DOM,而是将then(..)
附加到异步调用。让我们来做。
我们模拟异步调用并通过结果更新状态。此外,由于我们可能想从组件的范围中写出此功能,因此我们将其与上下文进行参数化,以便状态设置器可用:
// asyncFunc.js
const asyncFunc = ({setData}) =>
async (x) =>
new Promise((resolve, reject) => {
return setTimeout(() => resolve(x), 1000);
})
.then(setData)
我们首先在上下文中添加信号以在组件中共享数据:
// context.js
import {createSignal} from from "solid-js";
const [data, setData] = createSignal("");
const context = {
data, setData,
...
}
在solidjs中使用createRessource
处理异步调用:它可以进行论证并返回getter函数(以(argOfFun, Fun)
的形式编写)。
import { createEffect, createResource } from "solid-js";
import context from "./context";
import asyncFunc from "./asyncFunc";
const comp3 = (ctx) => {
// import the state
const {data, setData, theme} = ctx;
const AsyncFun = asyncFunction(ctx)
return function Comp1(props) {
// run the async function; it will update the state
const [result] = createResource(100, AsyncFun);
return(
<p> Async render: {result()}</p>
)
}
}
您可以通过以上导入状态data
在其他地方使用它,当您导航时,组件将是最新的。
请注意,函数组件只能运行 ,因此,异步函数将仅运行 。。
如果我们想更改它怎么办?让我们举个例子。我们使用滑块来更改异步函数的参数。
我们使用本地状态来跟踪显示值;这意味着每次渲染组件时都会重置。如果需要持久性,可以选择全球状态。
我们需要实现2个异步调用:第一个调用将在组件渲染时运行,而第二个将在组件终生期间的更改中做出反应。 SolidJS使这简单起来,因为我们可以放心该功能组件仅运行一次。
import ...
const comp4 = (ctx) => {
// import the state from context
const {data, setData} = ctx;
const AsyncFun = asyncFunction(ctx)
return ()=> {
// local state to display the slider values, reset on every mount
const [slide, setSlide] = createSignal(10);
// initial async call that updates the "data" state
const [initial] = createResource(slide(), AsyncFun);
return (
<div>
<input
type="range"
min="10"
max="100"
value="10"
onchange={({target: {value}) => {
setSlide(value);
// dynamic async call
createResource(value, AsyncFun)
}}
/>
<p>{slide()}</p>
<p>First async render: {initial()}</p>
<p> Dynamic async update: {data()}.</p>
</div>
)
任何其他组件都可以访问反应性状态data
。