我正在学习React Hooks,并且想知道什么是“钩子友好”时重新加载数据的最有效方法。
我确定了3个用例(最新的显然是“更合适的”
使用已复制的代码
//Example of Using useEffect Hooks by duplicating code
import React, {useState, useEffect} from 'react'
import axios from 'axios'
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}, [setDeals])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => {
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
}).catch(res => {
setDeals([{label: 1, label: 2}])
setLoading(false)
})
}}>Fetch Again</button>
</div>
)
}
通过在外部函数内部传递钩子。代码重用-在另一个函数中使用钩子 我了解这不是使用钩子的“方式”,尽管这是我的第一个首选解决方案
//Example of Using useEffect Hooks by feeding hooks to external function
import React, {useState, useEffect} from 'react'
import axios from 'axios'
const usefetchMore = (setDeals, setLoading) => {
console.log("usefetchMore")
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
useEffect(() => {
usefetchMore(setDeals, setLoading)
}, [setDeals])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => usefetchMore(setDeals, setLoading)}>Fetch Again</button>
</div>
)
}
这似乎是“正确的做法”,它基于重新触发useEffect
,因为它正在监听reload
变量的更改,该变量只是为了重新触发它。
//Example of Using useEffect Hooks with variable to re-trigger useEffect
import React, {useState, useEffect} from 'react'
import axios from 'axios'
/* DOESN't WORK */
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
const [reload, setReload] = useState(0)
useEffect(() => {
console.log("Deal4.useEffect")
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}, [setDeals, reload])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => {
setReload(reload + 1)
}}>Fetch Again</button>
</div>
)
}
我的问题是:如果我要构建一个显示加载并允许刷新的组件,那用“ React hooks”编写它的正确方法是什么?
答案 0 :(得分:0)
在/ src /中创建一个名为Photos.js的组件,并为其提供基本列表:
import React from "react";
import { useFetch } from "./hooks";
function Photos() {
const [data, loading] = useFetch(
"https://jsonplaceholder.typicode.com/photos?albumId=1"
);
return (
<>
<h1>Photos</h1>
{loading ? (
"Loading..."
) : (
<ul>
{data.map(({ id, title, url }) => (
<li key={`photo-${id}`}>
<img alt={title} src={url} />
</li>
))}
</ul>
)}
</>
);
}
export default Photos;
现在我们需要一个挂钩!在同一目录中创建一个名为hooks.js的文件,并使用以下文件填充该文件:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
async function fetchUrl() {
const response = await fetch(url);
const json = await response.json();
setData(json);
setLoading(false);
}
useEffect(() => {
fetchUrl();
}, []);
return [data, loading];
}
export { useFetch };
将“照片”组件导入App.js,然后开始执行yarn。完成!