当我想要显示来自API的数据时出错



在我试图设置的屏幕中。我得到一个产品的ID。上一个屏幕是来自API的产品列表。由于props.data,我获得了此idconsole.log('rops',this.props.data(运行良好,无论点击了什么产品,都会向我返回正确的ID。有了这个产品的ID,我想找到这个产品的详细信息(参考资料、家庭、价格、库存等(。我创建这个函数是为了通过我的API调用产品细节。

initListData = async () => {
if (parseInt(this.state.productId) > 0) {
let product_data = await getProduct(this.state.productId);
console.log('product_data', product_data)
this.setState({
displayArray: product_data,
loadMoreVisible: (product_data.length >= 15 ? true : false),
currentPage: 2
});
}
};

我认为问题是displayArray[]是空的,所以

let product_data=wait getProduct(this.state.productId(;

不起作用。

我得到了这个错误:无法从不同组件的函数体内部更新组件你能向我解释一下怎么了吗?

全代码

export default class Information extends Component {
constructor(props) {
super(props);
this.state = {
productId: this.props.data,
displayArray: [],
}
console.log('props', this.props.data) // ok, ça fonctionne, on récupère bien l'ID du produit cliqué
};
initListData = async () => {
if (parseInt(this.state.productId) > 0) {
let product_data = await getProduct(this.state.productId);
console.log('product_data', product_data)
this.setState({
displayArray: product_data,
loadMoreVisible: (product_data.length >= 15 ? true : false),
currentPage: 2
});
}
};
async UNSAFE_componentWillMount() {
this.initListData();
}
render() {
console.log('ça c'est data = ', this.props.data );
console.log('ça c'est les props =', this.props );
console.log('ça c'est le state = ', this.state );

return (
<ScrollView contentContainerStyle={{flex: 1}}>
{
this.state.displayArray.map((item, i) => (
<ListItem bottomDivider>
<Icon name='flight-takeoff' />
<ListItem.Content>
<ListItem.Title style={{color: '#d35400'}}>{item.name}</ListItem.Title>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.family")}: {item.family_id}
</ListItem.Subtitle>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.reference")}: {item.reference}
</ListItem.Subtitle>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.id")}: {item.id}
</ListItem.Subtitle>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.cost")}: {item.cost}
</ListItem.Subtitle>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.description")}: {item.description}
</ListItem.Subtitle>
<ListItem.Subtitle style={{ color: '#F78400' }}>
{i18n.t("information.stock")}: {item.stock_status}
</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
))
}
</ScrollView>
);
}
}

getProduct函数:[我只需要隐藏真实的url]

export async function getProduct(product_id) {
const abortController = new AbortController();
let user_id = await retrieveProfileUserId();
let lang = await retrieveAppLang();
let access_token = await renewAccessToken();
let result = {};
if (parseInt(product_id) > 0 && access_token != '' && parseInt(user_id) > 0) {
try {
let response = await fetch(
API_URL +
"/products/" + product_id +
"?user_id=" + user_id +
"&society_id=" + API_SOCIETYID +
"&access_token=" + access_token +
"&lang=" + lang,
{
method: "GET",
signal: abortController.signal,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "Bearer " + API_SECRETKEY,
"Cache-Control": "no-cache, no-store, must-revalidate",
Pragma: "no-cache",
Expires: "0"
}
}
)
.then(response => response.json())
.then(responseData => {
if (responseData.status == 200 && responseData.data) {
console.log("getProduct()::success", responseData.data);
result = responseData.data;
} else if (
responseData.status >= 200 && responseData.status <= 404 &&
responseData.data.error && responseData.data.error.length >= 3
) {
// Handle error
throw responseData.data.error;
} else {
throw "error";
}
});
} catch (error) {
//console.log(error);
abortController.abort();
}
}

试着改变一些事情,它应该会起作用。

我也不喜欢直接在fn中设置状态,所以我建议进行以下更改:

initListData = async () => {
if (this.props.data != null) {
const productData = await getProduct(this.state.productId);
return productData; // You are missing this, this is vital!
}
};
async componentDidMount() {
const data = await this.initListData(); // don't forget await here if you're using async
if (data.id) {
this.setState((prevState) => ({
displayArray: [...prevState.displayArray, data],
loadMoreVisible: ..., // I don't know what do you want here, because again, you receive an object from your backend, not an array.
currentPage: 2
}));
}
}

最新更新