刷新后,React道具变成不确定的
我是从API中获取的,在该API中,我想从app.js将响应对象作为prop将其传递给子组件,然后在我的tags.js文件中使用它。但是,它仅在一次后起作用,当我刷新它时,它给我一个错误,说props.response.names.length是未定义的。我尝试使用使用效果函数尝试更新它,但它不起作用。感谢任何帮助。
我的app.js文件(仍然是运行“ npx create-react-app my-app”时的一些残余物)):
import './App.css';
import Tags from './Tags.js';
import React, { useState, useEffect } from 'react';
function App() {
const makeRequest = async () => {
try {
let response = await fetch('RANDOM_API_URL');
let json = await response.json();
setResponse(json);
} catch (error) {
console.log(error);
}
}
const [response, setResponse] = useState(makeRequest);
useEffect(() => {
setResponse(makeRequest);
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Tags response={response}></Tags>
</div>
);
}
export default App;
我的tags.js:
import './App.js';
function Tags(props) {
const makeButtons = () => {
let result = [];
for (let i = 0; i < props.response.names.length; i++) {
result.push(<button key={i}>hello</button>);
}
return result;
}
return (
<div>
{makeButtons()}
</div>
);
}
export default Tags;
I'm fetching from an API where I want to pass the response object as a prop onto a child component from App.js and use it in my Tags.js file. However, it only works after one time and when I refresh it, it gives me an error saying the props.response.names.length is undefined. I tried using the useEffect function to try and update it but it didn't work. I would appreciate any help.
My App.js file (still some remnants of when you run "npx create-react-app my-app"):
import './App.css';
import Tags from './Tags.js';
import React, { useState, useEffect } from 'react';
function App() {
const makeRequest = async () => {
try {
let response = await fetch('RANDOM_API_URL');
let json = await response.json();
setResponse(json);
} catch (error) {
console.log(error);
}
}
const [response, setResponse] = useState(makeRequest);
useEffect(() => {
setResponse(makeRequest);
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Tags response={response}></Tags>
</div>
);
}
export default App;
My Tags.js:
import './App.js';
function Tags(props) {
const makeButtons = () => {
let result = [];
for (let i = 0; i < props.response.names.length; i++) {
result.push(<button key={i}>hello</button>);
}
return result;
}
return (
<div>
{makeButtons()}
</div>
);
}
export default Tags;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的makerequest功能是异步的,并在内部设置状态。获得此错误的原因是,您并不总是有一个
wenders.names
要读取长度 - 您只有一个空响应
对象。要么确保您始终具有状态中可用的
name
数组,要么避免在状态中不存在名称时呈现标签组件。另外,尝试避免使用您的依赖阵列创造性,它是有原因的。我明白为什么您在其中不包含
makerequest
,因为您在每个渲染上创建一个新功能。当您从类组件过渡到功能组件时,这是要牢记的。类方法在各个渲染中都是稳定的,功能组件中声明的函数却不是。要模仿类方法,您可以使用usecallback挂钩声明功能,但是您需要再次包含依赖项数组。在您的情况下,您可以在使用效果内创建异步函数,然后调用它。向标签提供默认的
响应
Prop prop将确保您甚至可以在响应之前读取name
的长度。更仔细地查看您的标签组件,我认为应该是这样的:
不要使用索引作为钥匙,如果您重新排列数组中的名称,就会引起问题。而且我想您想为按钮提供一个单击功能。
Your makeRequest function is async, and sets state internally. The reason you get this bug is that you don't always have a
response.names
to read length from - you only have an emptyresponse
object.Either make sure you always have the
names
array available in state, or avoid rendering your Tags component when names is not present in state.Also, try to avoid being creative with your dependency array, it's there for a reason. I see why you didn't include
makeRequest
in it though, since you create a new function on every render. That's something to keep in mind when you transition from class components to functional components. Class methods are stable across renders, functions declared in a functional component are not. To mimic a class method, you can declare functions using the useCallback hook, but again you need to include the dependency array. In your case, you can just create the async function inside useEffect, and then call it.Supplying a default
response
prop to Tags will make sure you can read the length ofnames
even before you have a response.Looking more closely on your Tags component, I think it should be something like this:
Don't use index as key, that will cause problems if you rearrange the names in your array. And I guess you want to supply an onClick function to your buttons.