React Signals 是一个轻量级的状态管理库,它提供了一种简单而强大的方式来管理 React 应用中的状态。它的 API 设计受到了 SolidJS 的启发,使用起来非常直观。
该架构和被合入vue3.6 vapor分支的alien-signals 是一样的!
地址:https://github.com/hunghg255/reactjs-signal/tree
import { createSignal } from "reactjs-signal";
// 创建一个初始值为 0 的信号
export const count = createSignal(0);
有三种主要方式可以在组件中使用信号:
import { useSignal } from "reactjs-signal";
import { count } from "../signals/counter";
export const Counter = () => {
const [value, setValue] = useSignal(count);
return (
<div>
<p>Count: {value}</p>
<button onClick={() => setValue((v) => v + 1)}>Increment</button>
</div>
);
};
import { useSignalValue } from "reactjs-signal";
import { count } from "../signals/counter";
export const Display = () => {
const value = useSignalValue(count);
return <div>Current count: {value}</div>;
};
import { useSetSignal } from "reactjs-signal";
import { count } from "../signals/counter";
export const Controls = () => {
const setCount = useSetSignal(count);
return (
<div>
<button onClick={() => setCount((v) => v + 1)}>+1</button>
<button onClick={() => setCount((v) => v - 1)}>-1</button>
</div>
);
};
计算信号允许你基于其他信号创建派生状态:
import { createSignal, createComputed } from "reactjs-signal";
const count = createSignal(0);
const doubleCount = createComputed(() => count() * 2);
const isEven = createComputed(() => count() % 2 === 0);
使用 useSignalEffect
可以在信号值变化时执行副作用:
import { useSignalEffect } from "reactjs-signal";
import { count } from "../signals/counter";
export const Logger = () => {
useSignalEffect(() => {
console.log("Count changed:", count());
});
return null;
};
如果你需要在服务端渲染时初始化信号值:
import { useHydrateSignal } from "reactjs-signal";
import { count } from "../signals/counter";
export const App = () => {
// 在组件挂载时将 count 信号的值设置为 10
useHydrateSignal(count, 10);
return <div>...</div>;
};
useSignalValue
当只需要读取值时useSetSignal
当只需要更新值时createComputed
来缓存计算结果import { createSignal, createComputed } from"reactjs-signal";
exportinterface Todo {
id: number;
text: string;
completed: boolean;
}
exportconst todos = createSignal<Todo[]>([]);
exportconst filter = createSignal<"all" | "active" | "completed">("all");
exportconst filteredTodos = createComputed(() => {
const currentFilter = filter();
const currentTodos = todos();
switch (currentFilter) {
case"active":
return currentTodos.filter((todo) => !todo.completed);
case"completed":
return currentTodos.filter((todo) => todo.completed);
default:
return currentTodos;
}
});
import { useSignal, useSignalValue } from"reactjs-signal";
import { todos, filter, filteredTodos } from"../signals/todos";
exportconst TodoApp = () => {
const [, setTodos] = useSignal(todos);
const [currentFilter, setFilter] = useSignal(filter);
const visibleTodos = useSignalValue(filteredTodos);
const addTodo = (text: string) => {
setTodos((prev) => [
...prev,
{
id: Date.now(),
text,
completed: false,
},
]);
};
return (
<div>
<input
type="text"
onKeyPress={(e) => {
if (e.key === "Enter") {
addTodo(e.currentTarget.value);
e.currentTarget.value = "";
}
}}
/>
<ul>
{visibleTodos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<div>
<button onClick={() => setFilter("all")}>All</button>
<button onClick={() => setFilter("active")}>Active</button>
<button onClick={() => setFilter("completed")}>Completed</button>
</div>
</div>
);
};
记住,信号的主要优势在于其简单性和响应式特性,这使得状态管理变得更加直观和高效。
今天的分享就到这里了,如果文章中有问题,欢迎指正!
如果对你有帮助,记得关注我