我正在学习本教程中的上下文示例,我从该示例中了解到的是使用自定义提供程序:
import { createSignal, createContext, useContext } from "solid-js";
const CounterContext = createContext();
export function CounterProvider(props) {
const [count, setCount] = createSignal(props.count || 0),
counter = [
count,
{
increment() {
setCount((c) => c + 1);
},
decrement() {
setCount((c) => c - 1);
},
},
];
return (
<CounterContext.Provider value={counter}>
{props.children}
</CounterContext.Provider>
);
}
export function useCounter() {
return useContext(CounterContext);
}我有三个问题:
<CounterContext.Provider value={counter}>。再和createSignal一起使用在计数器上?那么,依赖关系是:createSignal->CounterProvider?
const SomeContext = createContext({
someProp: "defaultString",
someAction: function(){
console.log('something')
}
});发布于 2022-11-18 16:47:56
没有自定义上下文,因为所有上下文都是自定义的。而且,也没有规范,因为这个想法非常简单。
Context是一种在不遍历组件层次结构的情况下向组件树传递值的方法。基本上,它是一个JavaScript作用域,组件直接从其中获取值,而不是手动将道具传递到组件树。记住,与React不同的是,Solid的组件被编译成JavaScript函数,函数可以从其外部作用域访问值。
Context.Provider封装内部组件,并通过使用常规的JavaScript作用域链提供值。useContext在其外部作用域中查找提供的上下文,如果存在,则获取值(如果没有使用默认值)。在同一上下文的多个提供者的情况下,最内部的一个将如我们所期望的那样使用,因为变量查找从内部范围到最外层的范围。
要了解更多信息,您可以阅读React的上下文文档,坚实地借用来自React的上下文API的想法。
该示例看起来很复杂,因为具有存储在上下文中的方法的对象尝试一个更简单的对象。
import { createContext, useContext } from 'solid-js';
import { render } from 'solid-js/web';
const CounterContex = createContext<number>(0);
const Child = () => {
const count = useContext(CounterContex);
return (
<div>{count}</div>
);
};
const App = () => {
return (
<div>
<CounterContex.Provider value={10}>
<Child />
</CounterContex.Provider>
</div>
);
}
render(App, document.querySelector('#app'));如果不提供值,则将使用默认值:
import { createContext, useContext } from "solid-js";
import { render } from "solid-js/web";
const CounterContex = createContext<number>(0);
const Child = () => {
const count = useContext(CounterContex);
return <div>{count}</div>;
};
const App = () => {
return (
<div>
<Child />
</div>
);
};
render(App, document.querySelector("#app"));可以在组件树的不同级别覆盖上下文值:
import { createContext, useContext } from "solid-js";
import { render } from "solid-js/web";
const CounterContex = createContext<number>(0);
const Child = () => {
const count = useContext(CounterContex);
return <div>{count}</div>;
};
const App = () => {
return (
<div>
<CounterContex.Provider value={10}>
<Child />
<CounterContex.Provider value={20}>
<Child />
</CounterContex.Provider>
</CounterContex.Provider>
</div>
);
};
render(App, document.querySelector("#app"));现在,让我们在上下文中存储一个信号,并在子组件中使用:
import { createContext, useContext, createSignal } from "solid-js";
import { render } from "solid-js/web";
const [count, setCount] = createSignal(0);
const CounterContex = createContext({
count,
setCount,
});
const Child = () => {
const { count, setCount } = useContext(CounterContex);
return (
<div onClick={() => setCount(count() + 1)}>
Click to increment: {count()}
</div>
);
};
const App = () => {
return (
<div>
<Child />
</div>
);
};
render(App, document.querySelector("#app"));让我们重构前面的示例。在本文中,我们将使用undefined作为默认值,但稍后使用上下文提供程序从信号中用getter和setter覆盖它:
import { createContext, useContext, createSignal } from "solid-js";
import { render } from "solid-js/web";
const CounterContex = createContext<any>();
const Child = () => {
const { count, setCount } = useContext(CounterContex);
return (
<div onClick={() => setCount(count() + 1)}>Click to increment: {count}</div>
);
};
const [count, setCount] = createSignal(0);
const App = () => {
return (
<div>
<CounterContex.Provider value={{ count, setCount }}>
<Child />
</CounterContex.Provider>
</div>
);
};
render(App, document.querySelector("#app"));现在是实现您发布的示例的时候了。您的组件包装在一个名为CounterProvider的组件中,但我将明确地发布它。您可以随时将逻辑移动到组件中:
import { createContext, useContext, createSignal } from "solid-js";
import { render } from "solid-js/web";
const CounterContex = createContext<any>();
const Child = () => {
const [count, { increment, decrement }] = useContext(CounterContex);
return (
<div>
<div>{count()}</div>
<div onClick={() => increment()}>Click to Increment</div>
<div onClick={() => decrement()}>Click to Decrement</div>
</div>
);
};
const [count, setCount] = createSignal(0);
const o = [
count,
{
increment() {
setCount((c) => c + 1);
},
decrement() {
setCount((c) => c - 1);
},
},
];
const App = () => {
return (
<div>
{/* This time we use an array rather than an object as the context value */}
<CounterContex.Provider value={o}>
<Child />
</CounterContex.Provider>
</div>
);
};
render(App, document.querySelector("#app"));现在回答你的问题:
CounterContext只是一个封装CounterContext.Provider组件以使其更易于使用的组件。它不是API的一部分。https://stackoverflow.com/questions/74491479
复制相似问题