Last Updated on : 2024-06-05 03:14:27download
This topic uses basic-ts-0.59 basic as an example, it introduces the specific features and how to use them. For more resources, please go to tuya-panel-demo GitHub repository.
This project depends on
TYSdk.mobile.mobileInfo.appRnVersion
5.28 or later. If the app version is too old, please go to Tuya Panel - RN and download it again.
├── .babelrc ├── .eslintignore ├── .eslintrc.base.js ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.js ├── .versionrc ├── CHANGELOG.md ├── README-zh_CN.md ├── README.md ├── index.android.js // Android entrance ├── index.ios.js // iOS portal ├── index.js // Android entrance(for compatibility) ├── package.json ├── rn-cli.config.js ├── src │ ├── api // A series of cloud APIs used in the project │ ├── components // Put the reusable functional components used in the project │ ├── composeLayout.tsx // Encapsulation processes some device events and device information needed inside the panel │ ├── config // Place some commonly used configuration files inside the panel │ ├── i18n // Place multi-language configuration files │ ├── main.tsx // The project entry file is inherited from the 'navigator layout'. Some necessary configurations, such as background and topbar, are passed in by rewriting the 'hookroute' method. The 'renderscape' method is overridden to control the route jump │ ├── models // Put some code related to Redux │ ├── pages // Places the components at each page level of the project │ ├── res // Put local resources, including pictures, SVG path, etc │ └── utils // Put some common tools and methods used to place the panel interior ├── tsconfig.json // TS configuration file └── yarn.lock
Put a series of cloud APIs used in the project
Define API
import { TYSdk } from 'tuya-panel-kit';
// tips: TYSdk.apiRequest Generic support is provided to make the code more elegant~
export const someApiFn = () => {
return TYSdk.apiRequest<any>('tuya.some.api.name', {});
};
Using the API
import * as api from '@api';
api.someApiFn().then(data => console.log(data));
Place reusable functional components used in the project
Place some common configuration files inside the panel
Place multilingual configuration files. For specific redundant usage, please refer to Internationalization
Put some code related to redux
, the internal common module encapsulates some commonly used states
and actions
;
Put some code related to redux, the internal common module encapsulates some commonly used States and actions;
import { View } from 'react-native';
import { TYText } from 'tuya-panel-kit';
import { useSelector } from '@models';
const SomeFCComponent: React.FC = () => {
const dpState = useSelector(state => state.dpState);
return (
<View>
<TYText text={JSON.stringify(dpState)} />
</View>
);
};
import { View } from 'react-native';
import { useDispatch } from 'react-redux';
import { TYSdk, TYText, Button } from 'tuya-panel-kit';
import { useSelector, actions } from '@models';
const SomeFCComponent: React.FC = () => {
const dispatch = useDispatch();
const handleClick = () => {
dispatch(actions.common.updateDp({ yourDpCode: 'yourDpValue' }));
// It can also be directly update DpState through the method in TYSdk.device
// TYSdk.device.putDeviceData({ yourDpCode: 'yourDpValue' });
};
return (
<View>
<Button text="Publish DP" onPress={handleClick} />
</View>
);
};
import { View } from 'react-native';
import { TYText } from 'tuya-panel-kit';
import { useSelector } from '@models';
const SomeFCComponent: React.FC = () => {
const devInfo = useSelector(state => state.devInfo);
return (
<View>
<TYText text={JSON.stringify(devInfo)} />
</View>
);
};
Place the components of each page level of the project, in which the following two pages are built-in in the project:
consoleLayout
is the log output component issued and reported by DP, and contentLayout
is the component below the interactive control of DP;Place local resources, including images, SVG path, etc., which can be referenced by @res
index.ts File, which we built in read.js File can be used to quickly traverse the new image file generation index.ts File export, the specific command can refer to the following example;
Some common tools and methods are used to place the panel interior;
The high-order functioncomposeLayout
works in three ways:
During panel initialization,composeLayout
processes the original devInfo
and initializes the redux store
.
When the panel is running,composeLayout
monitors events related to device changes and updates the information to the corresponding redux store
in real-time.
Associate the current component with the redux store
through theconnect
function.
import _ from "lodash";
import PropTypes from "prop-types";
import React, { Component } from "react";
import { Provider, connect } from "react-redux";
import { TYSdk, Theme } from "tuya-panel-kit";
import {
devInfoChange,
deviceChange,
responseUpdateDp,
} from "./redux/modules/common";
import theme from "./config/theme";
const TYEvent = TYSdk.event;
const TYDevice = TYSdk.device;
/**
*
* @param {Object} store: redux store
* @param {ReactComponent} component: the component that needs to be connected to the `redux store`. It is usually the main component.
*/
const composeLayout = (store, component) => {
const NavigatorLayoutContainer = connect(_.identity)(component);
const { dispatch } = store;
/**
* This function monitors the event of `device data change`.
* When a DP's data is changed, it will synchronize the changed DP status to `redux`.
* Similarly, when device information is changed, it will synchronize the changed device information to `redux`.
*/
TYEvent.on("deviceDataChange", (data) => {
switch (data.type) {
case "dpData":
dispatch(responseUpdateDp(data.payload));
break;
default:
dispatch(deviceChange(data.payload));
break;
}
});
/**
* This function monitors the event of `network status change`.
* When device information is changed, it will synchronize the changed device information to `redux`.
*/
TYEvent.on("networkStateChange", (data) => {
dispatch(deviceChange(data));
});
class PanelComponent extends Component {
static propTypes = {
// eslint-disable-next-line
devInfo: PropTypes.object.isRequired,
};
/**
* If `devInfo` exists (usually it exists) when the panel enters,
* This function will call `setDeviceInfo` to process the original `devInfo`, and then pass in `redux`.
*
* If `devInfo` does not exist when the panel enters,
* This function will call `getDeviceInfo` to asynchronously acquire the processed `devInfo`, and then pass in `redux`.
*/
constructor(props) {
super(props);
if (props && props.devInfo && props.devInfo.devId) {
TYDevice.setDeviceInfo(props.devInfo);
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
// eslint-disable-next-line
} else if (props.preload) {
// do something
} else {
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
}
}
render() {
return (
<Provider store={store}>
<Theme theme={theme}>
<NavigatorLayoutContainer />
</Theme>
</Provider>
);
}
}
return PanelComponent;
};
export default composeLayout;
To be brief, the entry componentMainLayout
function only works in one way: It inherits fromNavigatorLayout
, and helps manage multiple pages inside the panel.
import React from 'react';
import { StatusBar } from 'react-native';
import { Dispatch } from 'redux';
import {
TYSdk,
NavigatorLayout,
NavigationOptions,
DeprecatedNavigator,
DeprecatedNavigatorRoute,
} from 'tuya-panel-kit';
import composeLayout from './composeLayout';
import { store, ReduxState } from './models';
import Home from './pages/home';
import Setting from './pages/setting';
console.disableYellowBox = true;
type Props = ReduxState & { dispatch: Dispatch };
// Use it with caution. Do not turn it on production. If the console printing level is too deep, it will cause performance problems
// if (__DEV__) {
// console.log('TYSdk :', TYSdk);
// }
class MainLayout extends NavigatorLayout<Props> {
/**
*
* @desc hookRoute can do some control processing for specific routes here. For specific controllable parameters, please refer to [NavigationOptions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/tuya-panel-kit/index.d.ts) type definition
*/
hookRoute(route: DeprecatedNavigatorRoute): NavigationOptions {
const routeProps: NavigationOptions = {};
switch (route.id) {
case 'main':
break;
case 'setting':
routeProps.title = 'Setting';
routeProps.background = {
'3%': '#f82232',
'90%': '#FF624C',
};
break;
default:
break;
}
return {
...routeProps,
renderStatusBar: () => <StatusBar barStyle="default" />,
};
}
/**
* @desc
* You can use the ID in the route to determine which component to use.
* If there are extra props that need to be passed to page components, pass them here.
* Note that the route parameter comes from the TYSdk.Navigator.push.
* If you run TYSdk.Navigator.push ({ id: 'setting', title: 'Setting Page' });
* The routing stack is pushed, hookRoute and renderScape will receive route = { id: 'setting', title: 'setting page' },
* However, it should be noted that the route parameter of the home page is fixed as { id: 'main', initialRoute: true }
*
* @param {Object} route: route object.
* @param {object} navigator: Navigator object. For more information, see https://facebook.github.io/react-native/docs/0.43/navigator.html.
*/
renderScene(route: DeprecatedNavigatorRoute, navigator: DeprecatedNavigator) {
let component;
switch (route.id) {
case 'main':
component = <Home />;
break;
case 'setting':
component = <Setting />;
break;
default:
break;
}
return component;
}
}
export default composeLayout(store, MainLayout);
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback