🚀 探索100+强大的React Hooks可能性!访问 www.reactuse.com 获取完整文档和MCP支持,或通过 npm install @reactuses/core
安装,让我们丰富的Hook集合为您的React开发效率注入强劲动力!
楔子
最近在开发项目的时候,我对现有的状态管理方案都不太满意。总觉得写个状态管理要学这么多概念,有点太复杂了。于是我决定自己写一个:Neant
。
设计理念
我想要的状态管理库应该是这样的:
直接修改,就这么简单
typescript
import { createStore } from 'neant';
const { useAppStore } = createStore((setState) => ({
count: 0,
user: { name: 'John', age: 25 },
// 想改什么直接改
increment: () => setState(draft => {
draft.count += 1;
}),
updateUser: (name) => setState(draft => {
draft.user.name = name;
}),
}));
不需要想着怎么保持不可变,不需要各种spread操作符。你只需要专注业务逻辑。
自动性能优化
typescript
function UserInfo() {
const { user } = useAppStore(); // 只有user变化才重新渲染
return <div>{user.name}</div>;
}
function Counter() {
const { count } = useAppStore(); // 只有count变化才重新渲染
return <div>{count}</div>;
}
我希望性能优化是自动的。组件应该智能地订阅它真正用到的状态,其他状态的变化不应该影响它。
衍生状态就是Hook
typescript
const useDisplayName = () => {
const { user } = useAppStore();
return `${user.name} (${user.age}岁)`;
};
const useIsAdult = () => {
const { user } = useAppStore();
return user.age >= 18;
};
function UserProfile() {
const displayName = useDisplayName();
const isAdult = useIsAdult();
return (
<div>
<p>{displayName}</p>
<p>{isAdult ? '成年人' : '未成年'}</p>
</div>
);
}
为什么要发明新的概念呢?React的custom hook已经完美解决了衍生状态的问题。
最小使用例子
1分钟上手,从安装到运行:
bash
npm install neant
typescript
// store.js
import { createStore } from 'neant';
export const { useAppStore } = createStore((setState) => ({
// 状态
todos: [],
// 操作
addTodo: (text) => setState(draft => {
draft.todos.push({
id: Date.now(),
text,
completed: false,
});
}),
toggleTodo: (id) => setState(draft => {
const todo = draft.todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
}
}),
}));
typescript
// App.js
import { useAppStore } from './store';
function App() {
const { todos, addTodo, toggleTodo } = useAppStore();
return (
<div>
<button onClick={() => addTodo('新任务')}>
添加任务
</button>
{todos.map(todo => (
<div key={todo.id}>
<span
style={{
textDecoration: todo.completed ? 'line-through' : 'none'
}}
onClick={() => toggleTodo(todo.id)}
>
{todo.text}
</span>
</div>
))}
</div>
);
}
就这样,一个完整的todo应用就搞定了。
异步操作也很简单
typescript
const { useAppStore } = createStore((setState) => ({
posts: [],
loading: false,
fetchPosts: async () => {
setState(draft => { draft.loading = true; });
try {
const response = await fetch('/api/posts');
const posts = await response.json();
setState(draft => {
draft.posts = posts;
draft.loading = false;
});
} catch (error) {
setState(draft => { draft.loading = false; });
}
},
}));
异步就是异步,该怎么写就怎么写。不需要学习特殊的中间件或语法。
Next.js集成
对于Next.js的SSR支持,我也做了考虑:
typescript
// store-context.tsx
export const StoreProvider = ({ children, initialData }) => {
const storeRef = useRef(null);
if (storeRef.current === null) {
storeRef.current = createAppStore(initialData);
}
return (
<StoreContext.Provider value={storeRef.current}>
{children}
</StoreContext.Provider>
);
};
// page.tsx
export default async function Page() {
const serverData = await fetchServerData();
return (
<StoreProvider initialData={serverData}>
<MyApp />
</StoreProvider>
);
}
服务端数据可以直接注入到store,客户端无缝接手。
适合什么场景?
基于我的设计目标,Neant特别适合:
- 快速开发:不想花时间学复杂概念的项目
- 小到中型应用:不需要时光机调试的场景
- 团队协作:新人也能快速上手
- 注重体验:希望写状态管理像写普通JS一样
我的思考
在设计Neant的时候,我一直在想:状态管理库的本质是什么?
我觉得是让开发者能够专注业务逻辑,而不是被各种概念和模式分散注意力。最好的工具应该是"隐形"的------ 你感觉不到它的存在,但它帮你把事情做好了。
这就是为什么我给它起名"Neant"(法语"虚无"的意思)。我希望开发者在使用它的时候,能够忘记自己在用状态管理库,只是在写React。
如果你也认同这种理念,欢迎试试Neant。我会持续优化它,让React开发变得更简单。
项目地址:GitHub
有任何建议或问题,欢迎交流~