//index.js
import useList from "./hooks/useList";
function App() {
const { list, setList } = useList();
return (
<div className="App">
<h1>List</h1>
{list ? (
<ol>
{list.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ol>
) : (
"加载中..."
)}
</div>
);
}
//useList.js
import { useState, useEffect } from "react";
const useList = () => {
const [list, setList] = useState(null);
useEffect(() => {
ajax("/list").then(list => {
setList(list);
});
}, []); // [] 确保只在第一次运行
return {
list: list,
setList: setList
};
};
export default useList;
function ajax() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
{ id: 1, name: "Frank" },
{ id: 2, name: "Jack" },
{ id: 3, name: "Alice" },
{ id: 4, name: "Bob" }
]);
}, 2000);
});
}
在useList.js里,导出一个useList函数。我们把数据的初始化,ajax,和setList都放到这个函数里。外边只要调用我这个自定义的函数,就可以得到对list的读写接口。具体:使用useState初始化数据。使用useEffect在第一次渲染的时候发一个AJAX请求,请求成功就setList。然后把读写接口返回。
在App里边,只需要调用useList()就能拿到数据。
自定义hook就是把所有逻辑都放到一个函数里。通过调用函数拿到数据的读写接口。
效果:


给useList()再添加其他功能:添加项,删除某一项。
return {
list: list,
addItem: name => {
setList([...list, { id: Math.random(), name: name }]);
},
deleteIndex: index => {
setList(list.slice(0, index).concat(list.slice(index + 1)));
}
};
把对应的函数逻辑返回即可。