UseEffect 在初始渲染时触发
UseEffect firing on initial render
我正在为 API 创建一个前端,要求用户输入 API 密钥和设备名称。问题是 UseEffect() 提取是使用 'undefined' 作为呈现上的 API 键触发的,因此 API 抛出 401 错误代码并阻止页面呈现,因此用户可以输入密钥。
见下面的代码:
Api.js
const Api = ({ device, key }) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [device, key])
if (data) return (
<>
<tbody>
<tr>
<th>Date</th>
<th>Temp</th>
<th>C02</th>
</tr>
{data.samples.map((item) => (
<tr>
<td>{item.time}</td>
<td>{item.data[0]}</td>
<td>{item.data[1]}</td>
</tr>
))}
</tbody>
</>
)
return <div>No Data Found</div>
}
Home.js
const Home = ({ setDevice, setKey }) => {
const getData = (e) => {
e.preventDefault();
const newDevice = e.target.deviceID.value;
const apiKey = e.target.apiKey.value;
setDevice(newDevice);
setKey(apiKey);
}
return (
<>
<h1>Type in a device and provide an API key below:</h1>
<form onSubmit={getData}>
<input type='text' placeholder="Enter Device..." id='deviceID'></input>
<input style={{display: 'block'}} type='text' placeholder="Enter API Key..." id='apiKey'></input>
<button>Search</button>
</form>
</>
)
}
export default Home;
App.js
const App = () => {
const [device, setDevice] = useState()
const [key, setKey] = useState()
return (
<>
<Home setDevice={setDevice} setKey={setKey} />
<Api device={device} key={key} />
</>
)
}
export default App;
感谢任何帮助!!
您可以等到 key
& device
道具可用:
useEffect(() => {
key && device && fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [device, key])
useEffect
在第一次渲染后立即调用,不管依赖数组如何,所以上面的保护不会 运行 fetch
调用,直到这些变量可用(当依赖数组“看到”有变化并调用 useEffect
回调)。
如果 key
道具可能需要一段时间才能使用,您可能想要显示一个 loader。
我建议 de-couple 从 useEffect
获取数据的逻辑,因为你可能想直接调用 getData
,而且它也更适合测试和一般代码顺序.
const getData = (key, device) =>
key && device && fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData);
useEffect(() => {
getData(key, device)
}, [device, key])
此外,useState(null)
中的 null
也没有必要,因为 useState()
的行为相同。
您可以将 fetch 放在 if 语句中
useEffect(() => {
if(key && device){
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}
}, [device, key])
如果您打算在渲染时加载数据而不是之后加载更多数据,我将对您的 useEffect 挂钩进行以下更改:
useEffect(() => {
if(!device || !key || data) return null
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [data, device, key])
我正在为 API 创建一个前端,要求用户输入 API 密钥和设备名称。问题是 UseEffect() 提取是使用 'undefined' 作为呈现上的 API 键触发的,因此 API 抛出 401 错误代码并阻止页面呈现,因此用户可以输入密钥。
见下面的代码:
Api.js
const Api = ({ device, key }) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [device, key])
if (data) return (
<>
<tbody>
<tr>
<th>Date</th>
<th>Temp</th>
<th>C02</th>
</tr>
{data.samples.map((item) => (
<tr>
<td>{item.time}</td>
<td>{item.data[0]}</td>
<td>{item.data[1]}</td>
</tr>
))}
</tbody>
</>
)
return <div>No Data Found</div>
}
Home.js
const Home = ({ setDevice, setKey }) => {
const getData = (e) => {
e.preventDefault();
const newDevice = e.target.deviceID.value;
const apiKey = e.target.apiKey.value;
setDevice(newDevice);
setKey(apiKey);
}
return (
<>
<h1>Type in a device and provide an API key below:</h1>
<form onSubmit={getData}>
<input type='text' placeholder="Enter Device..." id='deviceID'></input>
<input style={{display: 'block'}} type='text' placeholder="Enter API Key..." id='apiKey'></input>
<button>Search</button>
</form>
</>
)
}
export default Home;
App.js
const App = () => {
const [device, setDevice] = useState()
const [key, setKey] = useState()
return (
<>
<Home setDevice={setDevice} setKey={setKey} />
<Api device={device} key={key} />
</>
)
}
export default App;
感谢任何帮助!!
您可以等到 key
& device
道具可用:
useEffect(() => {
key && device && fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [device, key])
useEffect
在第一次渲染后立即调用,不管依赖数组如何,所以上面的保护不会 运行 fetch
调用,直到这些变量可用(当依赖数组“看到”有变化并调用 useEffect
回调)。
如果 key
道具可能需要一段时间才能使用,您可能想要显示一个 loader。
我建议 de-couple 从 useEffect
获取数据的逻辑,因为你可能想直接调用 getData
,而且它也更适合测试和一般代码顺序.
const getData = (key, device) =>
key && device && fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData);
useEffect(() => {
getData(key, device)
}, [device, key])
此外,useState(null)
中的 null
也没有必要,因为 useState()
的行为相同。
您可以将 fetch 放在 if 语句中
useEffect(() => {
if(key && device){
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}
}, [device, key])
如果您打算在渲染时加载数据而不是之后加载更多数据,我将对您的 useEffect 挂钩进行以下更改:
useEffect(() => {
if(!device || !key || data) return null
fetch(`APILINK&key=${key}&id=${device}`)
.then((res) => res.json())
.then(setData)
}, [data, device, key])