首页 > 其他分享 >React中的另一种状态管理方案Valtio

React中的另一种状态管理方案Valtio

时间:2023-04-28 09:56:17浏览次数:33  
标签:Valtio const 方案 movie list React export import store

React中的状态管理是开发人员需要解决的问题。 总有一些新库给你选择,而选择合适的库可能是一项困难的工作

状态管理一直是React中开发人员需要解决的问题,如何有条理的组织数据,如何快速的在项目中集成,这些都是我们做项目时选择技术的标准。

Redux一直是我们react项目中不二的状态管理插件,但是redux的配置以及各种插件的安装一直是很多人员头疼的一个问题,太麻烦了。但是随着ReduxToolkit的出现,确实解决了这个问题,直接安装,就不再需要继续安装各类其他插件,直接上手就能用,简单方便。但是很多时候,我们的项目可能根本不需要这么笨重的插件,虽然redux很好,但是毕竟这么多年过去了,一代新人换旧人。前端这个大坑中,总会出现新的技术、框架来埋葬那些老家伙。

代理
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

自ES6版本以来,我们在JavaScript中有代理。 代理接收两个参数:

target - 要代理的原始对象
handler - 定义对象的操作
这是我们如何使用JavaScript创建代理的方式:

const handler = {
get: function (obj, prop) {
return prop in obj ? obj[prop] : 37;
},
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37

Valtio
Valtio是一个用于对React和JavaScript应用程序简单的代理状态的库。它使用了js中Proxy这个语法,能让我们可以非常方便的在react中集成状态管理功能。

npm init vite@latest # 创建react项目
npm i valtio # 进入项目,安装依赖

我们需要做的是包装我们的状态对象,然后我们可以在我们的应用程序中的任何地方进行改变:

import { proxy } from 'valtio';

type IStore = {
count: number;
list: Item[];
};

// 定义数据,使用proxy进行包括修饰
const store = proxy<IStore>({
count: 1,
list: [],
});

/**
* 改变数据
* @param step
*/
export const countPlus = (step: number) => {
store.count += step;
};

/**
* 新增数据到列表
* @param txt
*/
export const addToList = (txt: string) => {
store.list.push({
id: Date.now(),
txt,
});
};

export default store;

定义好的数据直接在组件中进行引入就能使用,useSnapshot可以获取我们定义好的状态数据,使用之后在组件中就是一个响应式的效果,只要数据改变了组件就会直接进行更新

import { useSnapshot } from 'valtio';
import store, { countPlus } from '../store';

function Counter() {
const { count } = useSnapshot(store);
return (
<div>
<h1>计数器--{count}</h1>
<button
onClick={() => {
countPlus(2);
}}
>
改变
</button>
</div>
);
}

export default Counter;

valtio简单直接,充分使用了proxy这个对象,简单粗暴的实现react项目的状态管理。在一些小型项目中是一个不错的选择。当然当然大家还是需要在项目中努力做好自己代码结构的组织方便后去数据的维护。

├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── readme.md
├── src
│ ├── @types
│ │ └── app.d.ts
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ └── react.svg
│ ├── components
│ │ ├── Counter.tsx
│ │ ├── List
│ │ │ ├── index.tsx
│ │ │ └── list-input.tsx
│ │ ├── Movies.tsx
│ │ └── ShowCounter.tsx
│ ├── index.css
│ ├── main.tsx
│ ├── store
│ │ ├── features
│ │ │ └── movie.ts
│ │ └── index.ts
│ └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

store,目录存储valtio的数据。index.ts做为入口,可以引入其他的子节点数据

store/features,目录可以根据功能做拆分处理。每一个功能对应一个文件

比如此处我的movie.ts文件的内容如下

// store/features/movie.ts
import { proxy } from 'valtio';
// 进行分割
export const movie = proxy({
movies: [],
});

export const loadMovieData = async () => {
const res = await fetch(
'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=2&data_type=1&mode=11&page_id=2&ret_num=48&session=ffad98ae609f650afe4b60e205948ac1&three_category_id=15;must'
).then((data) => data.json());
movie.movies = res.data.list;
};

完成的store/index.ts文件如下

import { proxy } from 'valtio';
import { movie } from './features/movie';

/**
* 定义数据
*/
const store = proxy<IStore>({
count: 1,
list: [],
movie, // 引入拆分好的文件
});

/**
* 改变数据
* @param step
*/
export const countPlus = (step: number) => {
store.count += step;
};

/**
* 新增数据到列表
* @param txt
*/
export const addToList = (txt: string) => {
store.list.push({
id: Date.now(),
txt,
});
};

export default store;

而我组件中如果要获取数据,可以直接拿来用

复制
// components/Movie.tsx
import { useEffect } from 'react';
import { useSnapshot } from 'valtio';
import store from '../store';
import { loadMovieData } from '../store/features/movie';

function Movies() {
const { movie } = useSnapshot(store); // useSnapshot取数据
// console.log(movie);
useEffect(() => {
loadMovieData();
}, []);
return (
<div className='movies'>
<ul>
{movie.movies.map((item: any) => (
<li key={item.albumId}>{item.name}</li>
))}
</ul>
</div>
);
}

export default Movies;

标签:Valtio,const,方案,movie,list,React,export,import,store
From: https://www.cnblogs.com/qian-fen/p/17360998.html

相关文章

  • redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化
    目录redis之持久化方案,主从复制,哨兵高可用,集群原理及搭建,缓存优化昨日内容回顾今日内容详细1持久化方案1.1RDB1.2aof方案1.3混合持久化2主从复制原理和方案3哨兵高可用4集群原理及搭建4.1集群搭建4.2集群扩容4.3集群缩容5缓存优化5.1redis缓存更新策略5.2缓存穿透击......
  • angularjs 拖拽实现方案
    最近有一个拖拽排序的功能遍历后无法直接读取index和item。换了一种思路实现功能<!DOCTYPEhtml><htmllang="en"ng-app="myApp"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,......
  • 提高网络安全性:探索ADAudit Plus的全功能IT安全审计解决方案
    数据安全一直是企业和组织的重要问题之一,而DataSecurityPlus作为一款数据安全解决方案,能够为企业提供全面的数据安全保障。首先,DataSecurityPlus可以对企业的敏感数据进行监控和审计,通过实时监控和记录文件、文件夹、数据库、邮件和打印机等资源的访问和操作,保障企业数据的安全性......
  • 除螨仪语音方案芯片推荐:NV040D 家用8脚语音ic
    随着时代的发展,大家对于健康的重视程度越来越高,而螨虫这类生物对于特殊群体来说,可能会带来皮肤问题,甚至引发呼吸道疾病,困扰生活,由此,清除床上的螨虫就成为了一个较为刚性的需求。除螨仪也就随之被发明,通过拍打、紫外线照射、吸尘和一定温度实现除螨操作,保持床铺清洁。 NV040D除......
  • 前端项目使用vw视口单位进行适配时字体大小的解决方案
    使用视口单位vw来实现响应式排版。1vw等同于视口宽度的百分之一,即如果你用vw来设定字体大小的话,字体的大小将总是随视口的大小进行改变。问题在于,当做上面的事情的时候,因为文本总是随着视口的大小改变大小,用户失去了放缩任何使用vw单位的文本的能力。所以你永远都不要只用viewpo......
  • 高保真智能录音机解决方案技术特色解析
    需求分析 随着数字化进程的不断推进,录音机的需求也在逐渐发生变化。用户对录音机的需求逐渐朝着,微型化,便携化,智能化的方向靠拢。鉴于此,团队根据市场的变化,及时推出了一系列高保真的数字录音机方案,方便系统集成厂商集成和运用,满足个性化的产品需求。 特色梳理 有趣的灵魂......
  • [React-Native]样式和布局
    一、基本样式(1)内联样式在组件里面定义样式<Textstyle={{color:'orange',fontSize:20}}>小字号内联样式</Text>(2)外联样式在组件里指向外面的样式<Textstyle={[styles.orange,styles.bigFontSize]}>大字号外联样式</Text>(3)样式具有覆盖性如果定义相同属性的样式,后面会覆......
  • 无界微前端方案官方示例,main-vue 项目打包之后 访问index.html页面空包,控制台报资源错
    报错信息: 修改方案: publicPath:“./”修改为如上配置即可。......
  • 前端跨域解决方案——CORS
    CORS(跨来源资源共享)是一种用于解决跨域问题的方案。CORS(跨来源资源共享)是一种安全机制,用于在浏览器和服务器之间传递数据时,限制来自不同域名的请求。在前端开发中,当通过XMLHttpRequest(XHR)或FetchAPI发送跨域请求时,如果服务器没有正确配置CORS,浏览器会阻止该请求,从而导致请求......
  • 解决方案下的项目版本号统一
    解决方案下的项目往往需要让生成的程序集版本号统一,最简单的方式当然是打开每一个项目下的AssemblyInfo.cs文件修改,或者使用项目属性修改。最近,发现还有一种更简单的方式,下面仔细介绍它。 步骤1、创建一个SolutionInfo.cs的文件,放到解决方案下。内容类似为: 步骤2、修改各......