使用自定义hooks封装数据获取逻辑
const useData = (url) => {
const [data, setData] = useState([]);
useEffect(() => {
fetch(url)
.then((response) => (response.json ? response.json() : response))
.then((data) => {
setData(data);
});
}, [url]);
return {
data,
};
};
渲染数据
function List(props) {
const { data } = props;
return data.map((item) => <div key={item.id}>{item.description}</div>);
}
function App() {
const { data } = useData('https://api.github.com/users/gaearon/gists');
return <List data={data} />;
}
分离列表和单个列表项的职责
List
是一个列表组件,它的职责是渲染列表,但这里我们额外的处理了单个列表项的渲染。
更好的做法是将这部分进行分离,List
只渲染列表,单个列表项的渲染细节抽离出来。
function ListItem(props) {
const { description } = props;
return <div>{description}</div>;
}
function List(props) {
const { data } = props;
return data.map((item) => (
<ListItem key={item.id} description={item.description} />
));
}
List和ListItem之间的耦合
观察上面的List
组件,我们会发现ListItem
被耦合在了List
内部,当我们需要更换不同的ListItem
时,需要深入到List
中进行修改,这会引入风险。
下面我们采用render prop
模式来解决这个问题。
function ListItem(props) {
const { description } = props;
return <div>{description}</div>;
}
function List(props) {
const { data, renderItem } = props;
return data.map(renderItem);
}
function App() {
const { data } = useData('https://api.github.com/users/gaearon/gists');
return (
<List
data={data}
renderItem={(item) => (
<ListItem key={item.id} description={item.description} />
)}
/>
);
}
List
现在不用关心列表项是什么了,它只需要执行renderItem
,并且还能适应未来各种不同的ListItem
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。