Redux
- src 业务源码目录
- constant 业务项目常量目录
- index.ts 常量定义文件
- devices 智能设备模型目录
- index.ts 定义并导出智能设备模型
- schema.ts 当前智能设备 DP 功能点描述
- pages 页面目录
- home 首页
- index.tsx 首页组件
- home 首页
- redux Redux 目录
- actions Redux Actions 目录
- network.ts Network Actions
- reducers Redux Reducers 目录
- network.ts Network Reducers
- index.ts Redux 入口
- store.ts Redux Store 定义
- actions Redux Actions 目录
- app.tsx App 根组件
- constant 业务项目常量目录
创建 Actions
// src/constant/index.ts
export const INIT_NETWORK = 'INIT_NETWORK';
export const CHANGE_NETWORK = 'CHANGE_NETWORK';
// src/redux/actions/network.ts
import { SmartDeviceModelNetwork } from '@ray-js/panel-sdk';
import { INIT_NETWORK, CHANGE_NETWORK } from '@/constant';
type UpdatePayload = Partial<SmartDeviceModelNetwork>;
const initNetwork = (payload: UpdatePayload) => {
return {
type: INIT_NETWORK,
payload,
};
};
const changeNetwork = (payload: UpdatePayload) => {
return {
type: CHANGE_NETWORK,
payload,
};
};
export const actions = {
initNetwork,
changeNetwork,
};
创建 Reducers
// src/redux/reducers/network.ts
import { SmartDeviceModel, SmartDeviceModelNetwork } from '@ray-js/panel-sdk';
import { INIT_NETWORK, CHANGE_NETWORK } from '@/constant';
import { devices } from '@/devices';
import { actions } from '../actions/network';
import { store } from '../store';
export type Actions = {
[K in keyof typeof actions]: ReturnType<typeof actions[K]>;
};
SmartDeviceModel.onInitialized(() => {
/**
* 这里 setTimeout 是为了保证在 devices.xxx 挂载上去以后再去 dispatch
*/
setTimeout(() => {
store.dispatch(actions.initNetwork({ ...devices.robot.network }));
devices.robot.onNetworkStatusChange((data) => {
store.dispatch(actions.changeNetwork(data));
});
}, 0);
});
const network = (
state = {} as Partial<SmartDeviceModelNetwork>,
action: Actions['changeNetwork'],
) => {
switch (action.type) {
case INIT_NETWORK: {
return {
...state,
...action.payload,
};
}
case CHANGE_NETWORK: {
return {
...state,
...action.payload,
};
}
default:
return state;
}
};
export const reducers = {
network,
};
定义 Store
// src/redux/store.ts
import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import { createLogger } from 'redux-logger';
import thunk from 'redux-thunk';
import { reducers as commonReducers } from './reducers/common';
import { reducers as networkReducers } from './reducers/network';
const reducers = {
...commonReducers,
...networkReducers,
};
type Reducers = typeof reducers;
export type ReduxState = { [K in keyof Reducers]: ReturnType<Reducers[K]> };
export const rootReducers = combineReducers(reducers);
const isDebuggingInChrome = !!window.navigator.userAgent;
const logger = createLogger({
predicate: () => true,
collapsed: true,
duration: true,
});
const middleware = isDebuggingInChrome ? [thunk, logger] : [thunk];
function configureStore(initialState?: Partial<ReduxState>) {
const appliedMiddleware = applyMiddleware(...middleware);
const store = createStore(
rootReducers,
initialState,
compose(appliedMiddleware),
);
return store;
}
export const store = configureStore();
使用 State
// src/pages/home/index.tsx
import React from 'react';
import { View } from '@ray-js/ray';
import { useSelector } from '@/redux';
export default function PageAppState() {
const network = useSelector((state) => state.network);
return (
<View style={{ flex: 1 }}>
{Object.keys(network || {}).map((key) => {
return <View key={key}>{`network.${key}: ${network[key]}`}</View>;
})}
</View>
);
}
👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。
Jotai
- src 业务源码目录
- atoms Jotai 原子状态目录
- network Network Atom
- index.ts
- network Network Atom
- devices 智能设备模型目录
- index.ts 定义并导出智能设备模型
- schema.ts 当前智能设备 DP 功能点描述
- pages 页面目录
- home 首页
- index.tsx 首页组件
- home 首页
- app.tsx App 根组件
- atoms Jotai 原子状态目录
创建 Atom
本例子只提供了基于 SDM network 静态属性的 atom 原子化方案,其他的静态属性 atom 原子化方案基本一致
// src/atoms/network/index.ts
import { atom } from 'jotai';
import { selectAtom } from 'jotai/utils';
import { SmartDeviceModel, SmartDeviceModelNetwork } from '@ray-js/panel-sdk';
import deepEqual from 'fast-deep-equal';
import { devices } from '@/devices';
type UpdatePayload = Partial<SmartDeviceModelNetwork>;
/**
* 定义一个 networkAtom
*
* 第一个参数传入默认值
* 第二个参数传入接受到 payload 时如何更新数据源
*
* 第一个泛型定义数据源的类型
* 第二个泛型定义修改数据源的 payload
*
* @docs 详见 https://jotai.org/docs/basics/primitives
*/
export const networkAtom = atom<SmartDeviceModelNetwork, UpdatePayload>(
null,
(get, set, payload) => {
set(networkAtom, { ...(get(networkAtom) || {}), ...payload });
},
);
/**
* 定义一个基于 networkAtom 的选择器
*
* 第一个参数传入源 atom 数据
* 第二个参数传入 selector 选择器匹配需要返回的数据
* 第三个参数传入 equalityFn 判断是否一致,有助于避免无效的渲染,提高性能,
*
* 第一个泛型定义数据源的类型
* 第二个泛型定义 selector 选择器匹配返回的数据的类型
*
* @docs 详见 https://jotai.org/docs/utils/select-atom
*/
export const selectNetworkAtom = selectAtom<
SmartDeviceModelNetwork,
SmartDeviceModelNetwork
>(networkAtom, (data) => data, deepEqual);
SmartDeviceModel.onInitialized(() => {
/**
* 这里 setTimeout 是为了保证在 devices.xxx 挂载上去以后再去给 Atom 赋值
*/
setTimeout(() => {
networkAtom.onMount = (setAtom) => {
setAtom({ ...devices.robot.network });
const id = devices.robot.onNetworkStatusChange((data) => {
setAtom({ ...data });
});
return () => devices.robot.offNetworkStatusChange(id);
};
}, 0);
});
使用 Atom
// src/pages/home/index.tsx
import React from 'react';
import { useAtomValue } from 'jotai';
import { View } from '@ray-js/ray';
import Section from '@/components/section';
import { selectNetworkAtom } from '@/atoms';
export default function PageAppState() {
const network = useAtomValue(selectNetworkAtom);
return (
<View style={{ flex: 1 }}>
{Object.keys(network || {}).map((key) => {
return <Section key={key} title={`network.${key}: ${network[key]}`} />;
})}
</View>
);
}
👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。