使用宿主平台数据
Lynx 允许宿主平台在页面加载时提供一份初始数据,并且在之后随时对这些数据进行更新。
这份初始数据被称为 initData
。
提供和更新数据
前置步骤
你需要完成接入现有应用中的指引,以确保你的应用已经集成了 Lynx,并对 Lynx 的 Native API 有基本的了解。
在使用 LynxView.loadTemplate()
加载一个 Bundle 的时候,你有机会传入一些数据:
LynxLoadMeta* meta = [LynxLoadMeta init];
// meta.url = @"";
// meta.binaryData = nil;
// meta.templateBundle = nil;
meta.initialData = __YOUR_DATA__;
// meta.loadOption = LynxLoadOptionDumpElement | LynxLoadOptionRecycleTemplateBundle;
[lynxView loadTemplate:meta];
LynxLoadMeta.Builder builder = new LynxLoadMeta.Builder();
// builder.setUrl();
// builder.setBinaryData();
// builder.setTemplateBundle();
builder.setInitialData(__YOUR_DATA__);
// builder.addLoadOption();
LynxLoadMeta meta = builder.build();
lynxView.loadTemplate(meta);
你可以在后续需要的时机通过 LynxView.updateData()
来更新这些数据:
LynxUpdateMeta* meta = [LynxUpdateMeta init];
meta.data = __YOUR_DATA__;
[lynxView updateData:meta];
LynxUpdateMeta.Builder builder = new LynxUpdateMeta.Builder();
builder.setUpdatedData(__YOUR_DATA__);
LynxUpdateMeta meta = builder.build();
lynxView.updateMetaData(meta);
你在加载时传入的数据和后续更新时传入的数据都可以在前端使用,下面是如何在前端使用这些数据。
使用数据
前端可以通过 useInitData()
来获取 initData
。
在宿主平台更新数据时,这些组件会自动重新渲染。
src/App.jsx
import { useInitData } from '@lynx-js/react';
function App() {
const initData = useInitData();
return (
<view>
<text>{initData.greeting}</text>
</view>
);
}
如果你使用传统的类组件,那么可以使用 InitDataConsumer
。
import { Component, InitDataProvider, InitDataConsumer } from '@lynx-js/react';
class C extends Component {
render() {
return (
<InitDataConsumer>
{(initData) => (
<view>
<text>{initData.greeting}</text>
</view>
)}
</InitDataConsumer>
);
}
}
注意 InitDataConsumer
必须作为 InitDataProvider
的子节点使用。
<InitDataProvider>
<view>
<C />
</view>
</InitDataProvider>
使用数据前进行预处理
虽然 useInitData()
会从宿主平台为你提供 initData
,但它可能不是你期望的格式。
想象一下,你有以下混乱的 initData
:
-
在 Android 上:
{
"pageTitle": "Hello Lynx"
}
-
但是,在 iOS 上:
{
"page_title": "Hello Lynx"
}
如果你想要兼容两个平台,你的代码可能会变得不那么干净:
import { useInitData } from '@lynx-js/react';
export function App() {
const initData = useInitData();
return (
<view>
<text>{initData.pageTitle || initData.page_title}</text>
</view>
);
}
上述场景只是示例,但 Lynx 确实提供了一种在使用之前处理 initData
的方法,它被称为 dataProcessor
。
使用默认dataProcessor
如果你(或宿主平台开发人员)没有指定 processorName
,Lynx 将使用 defaultDataProcessor
来处理 initData
。
src/index.tsx
import { root } from '@lynx-js/react';
import { App } from './App.js';
lynx.registerDataProcessors({
defaultDataProcessor: function (rawInitData) {
const { pageTitle, page_title, ...rest } = rawInitData;
return {
...rest,
pageTitle: pageTitle || page_title,
};
},
});
root.render(<App />);
if (import.meta.webpackHot) {
import.meta.webpackHot.accept();
}
然后,在你的组件中,你可以直接使用 initData
:
src/App.jsx
import { useInitData } from '@lynx-js/react';
export function App() {
const initData = useInitData();
return (
<view>
<text>{initData.pageTitle}</text>
</view>
);
}
使用命名的dataProcessor
你(或宿主平台开发人员)还可以在调用 LynxView.updateData()
时指定 processorName
:
LynxUpdateMeta *meta = [[LynxUpdateMeta alloc] init];
// TODO: set data and processorName
[lynxView updateData:meta];
LynxUpdateMeta meta = new LynxUpdateMeta();
// TODO: set data and processorName
lynxView.updateMetaData(meta);
因此,你定义的一个命名的 dataProcessor
将被调用来处理 initData
,你可以使用以下语法定义多个 dataProcessor
:
src/index.tsx
import { root } from '@lynx-js/react';
import { App } from './App.js';
lynx.registerDataProcessors({
dataProcessors: {
someDataProcessor: function (rawInitData) {
// process rawInitData
returnprocessedInitData;
},
anotherDataProcessor: function (rawInitData) {
// process rawInitData
returnprocessedInitData;
},
},
});
root.render(<App />);
if (import.meta.webpackHot) {
import.meta.webpackHot.accept();
}
如果业务逻辑需要,这允许你(或宿主平台开发人员)在宿主平台上决定使用哪个 dataProcessor
。