优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。
连载第三十九期
《高级指引:Use Provider Hook》
▽
useProvider Hook 可调用FlowApi生成的后台 API 接口,需要在 React Functional Components 中使用。
# 基本用法
Hook 运行在 onMount / componentDidMount 时。最后一个参数[]意味着它将运行 onMount,如果您将变量传递给它[someVariable],它会在更改值 onMount 时再次运行。
import React from "react";
import { useProvider } from "@next-core/brick-kit";
function Todos() {
// useProvider hook参数,args是provider的参数。
const options = {
args: [
"TEST_CHILD",
{ page: 1, page_size: 10 },
{ interceptorParams: { ignoreLoadingBar: true } },
],
};
// 最后一个参数`[]`意思是在`onMount`生命周期调用。
const {
loading,
error,
data = [],
} = useProvider("easyops.api.cmdb.instance@SearchTotal:1.2.0", options, []);
return (
<>
{error && "Error!"}
{loading && "Loading..."}
{data.map((todo) => (
<div key={todo.instanceId}>{todo.name}</div>
))}
</>
);
}
# 手动调用
import React from "react";
import { useProvider } from "@next-core/brick-kit";
function Todos() {
const options = {
args: ["TEST_CHILD", { page: 1, page_size: 10 }],
};
const request = useProvider("easyops.api.cmdb.instance@SearchTotal:1.2.0");
const addTodo = () => {
// 调用API。
request.query(["TEST_CHILD", { page: 1, page_size: 10 }]);
};
return (
<>
<button onClick={addTodo}>Add Todo</button>
{error && "Error!"}
{request.loading && "Loading..."}
{request.data.map((todo) => (
<div key={todo.instanceId}>{todo.name}</div>
))}
</>
);
}
// Or
import React from "react";
import { useProvider } from "@next-core/brick-kit";
function Todos() {
const request = useProvider();
const addTodo = () => {
// 调用API。
request.query("easyops.api.cmdb.instance@SearchTotal:1.2.0", [
"TEST_CHILD",
{ page: 1, page_size: 10 },
]);
};
return (
<>
<button onClick={addTodo}>Add Todo</button>
{request.error && "Error!"}
{request.loading && "Loading..."}
{request.data.map((todo) => (
<div key={todo.instanceId}>{todo.name}</div>
))}
</>
);
}
# Suspense Mode
import React, { Suspense } from "react";
import { useProvider } from "@next-core/brick-kit";
function Todos() {
const options = {
args: ["TEST_CHILD", { page: 1, page_size: 10 }],
// 使用suspense。
suspense: true,
};
const { data: todos = [] } = useProvider(
"easyops.api.cmdb.instance@SearchTotal:1.2.0",
options,
[]
);
return (
<>
{todos.map((todo) => (
<div key={todo.instanceId}>{todo.name}</div>
))}
</>
);
}
const App = () => (
<Suspense fallback="loading...">
<Todos />
</Suspense>
);
# 分页
import React, { Suspense } from "react";
import { useProvider } from "@next-core/brick-kit";
const Todos = () => {
const [page, setPage] = useState(1);
const { data, loading } = useProvider(
`easyops.api.cmdb.instance@SearchTotal:1.2.0`,
{
args: [
"TEST_CHILD",
{ page: page, page_size: 10 },
{ interceptorParams: { ignoreLoadingBar: true } },
],
transform: (currTodos, newTodos) => [...currTodos, ...newTodos], // 添加新的todos
data: [],
},
[page]
); // 当 onMount 和 `page` 更新时触发
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
{loading && "Loading..."}
{!loading && (
<button onClick={() => setPage(page + 1)}>Load More Todos</button>
)}
</ul>
);
};
const App = () => (
<div>
<Todos />
</div>
);
# 参数解构
// 数组解构
const [request, response, loading, error] = useProvider('easyops.api.cmdb.instance@SearchTotal:1.2.0');
// 对象解构
const {
request,
response,
loading,
error,
data,
query
} = useProvider('easyops.api.cmdb.instance@SearchTotal:1.2.0');
const {
loading,
error,
data,
query
} = request;
// Provider Options
const {
// 设置loading为false.
loading: false,
// 当发生错误时调用.
onError: (error) => ({}),
// 合并list数据或者返回某个字段的数据`newData.someObject`.
transform: (currData, newData) => ([...currData,...newData]),
// 开启React Suspense 模式.
suspense: false,
// 设置默认data.
data: [],
// provider参数.
args: [],
// 解构的http参数.
...HttpOptions
} = options;
有疑问加站长微信联系(非本文作者)