React native 要显示API中的数据时出错

React native 要显示API中的数据时出错,react-native,display,React Native,Display,在我试图搭建的屏幕上。我得到一个产品的ID。上一个屏幕是来自API的产品列表。多亏了道具数据,我才得到这个id console.log('props',this.props.data)工作正常,并将正确的ID返回给我,无论单击的产品是什么。 有了这个产品的ID,我想找到这个产品的详细信息(参考资料、系列、价格、库存等)。 我创建此函数是为了通过API调用产品详细信息 initListData = async () => { if (parseInt(this.state.produ

在我试图搭建的屏幕上。我得到一个产品的ID。上一个屏幕是来自API的产品列表。多亏了道具数据,我才得到这个id console.log('props',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[]是空的,所以

让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>
      );
    }
  }
导出默认类信息扩展组件{
建造师(道具){
超级(道具);
此.state={
productId:this.props.data,
displayArray:[],
}
console.log('props',this.props.data)//好的,关于récupère bien l'ID du produit cliqué
};
initListData=async()=>{
if(parseInt(this.state.productId)>0){
让product_data=wait-getProduct(this.state.productId);
console.log('product\u data',product\u data)
这是我的国家({
displayArray:product_数据,
loadMoreVisible:(product_data.length>=15?真:假),
当前页:2
});
}
};
异步不安全组件willmount(){
this.initListData();
}
render(){
log('ça c'est data=',this.props.data);
log('ça c'est les props=',this.props);
log('ça c'est le state=',this.state);
返回(
{
this.state.displayArray.map((项,i)=>(
{item.name}
{i18n.t(“information.family”)}:{item.family_id}
{i18n.t(“information.reference”)}:{item.reference}
{i18n.t(“information.id”)}:{item.id}
{i18n.t(“information.cost”)}:{item.cost}
{i18n.t(“information.description”)}:{item.description}
{i18n.t(“information.stock”)}:{item.stock_status}
))
}
);
}
}
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();
    }
  }
导出异步函数getProduct(产品标识){
const abortController=新的abortController();
让用户_id=wait retrieveProfileUserId();
let lang=等待检索applang();
让access_token=等待续订accesstoken();
让结果={};
if(parseInt(产品标识)>0&&access\u令牌!=''&&parseInt(用户标识)>0){
试一试{
let response=等待获取(
API_URL+
“/products/”+产品标识+
“?用户\u id=“+用户\u id+
“&society_id=“+API_SOCIETYID+
“&access\u token=“+access\u token”+
“&lang=“+lang,
{
方法:“获取”,
信号:abortController.signal,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
授权:“持有人”+API_保密密钥,
“缓存控制”:“无缓存,无存储,必须重新验证”,
Pragma:“无缓存”,
过期:“0”
}
}
)
.then(response=>response.json())
.然后(响应数据=>{
if(responseData.status==200&&responseData.data){
log(“getProduct()::success”,responseData.data);
结果=响应数据。数据;
}否则如果(
responseData.status>=200&&responseData.status=3
) {
//处理错误
抛出响应data.data.error;
}否则{
抛出“错误”;
}
});
}捕获(错误){
//console.log(错误);
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
      }));
    }
  }

只是为了确保这是明确的,我张贴了一个答案,以显示我现在的代码。 我希望我正确地理解了您Konstantin先生的解释,如果不是这样,我很抱歉,我按照您的建议修改了initListData和componentWillUnMount,但我的印象是我们没有输入componentDidMount,displayArray是空的。 在终端my console.log中,给出:

道具16 这是displayArray=Array[]

我没有console.log的任何内容('productData=',productData)

我得到3个黄色错误:

[未处理的承诺拒绝:引用错误:找不到变量: 产品数据]

[未处理的承诺拒绝:TypeError:this.initListData不是 函数。(在“this.initListData()”中,“this.initListData”未定义)

[未处理的承诺拒绝:TypeError:undefined不是对象 (评估‘data.length’)]

导出默认类信息扩展组件{
建造师(道具){
超级(道具);
此.state={
productId:this.props.data,
displayArray:[],
}
console.log('props',this.props.data)//好的,关于récupère bien l'ID du produit cliqué
};
initListData=async()=>{
如果(this.props.data!=null){
console.log('this.props.data=',this.props.data)//确定
const productData=await getProduct(this.state.productId);
}    
};
异步组件didmount(){
console.log('productData=',productData)
const data=wait this.initListData();//如果使用异步,请不要忘记在此处等待
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 (this.props.data != null) {
      console.log('this.props.data =', this.props.data) // OK 
      const productData = await getProduct(this.state.productId);
    }    
  };

  

  async componentDidMount() {
    console.log('productData=', productData)
    const data = await this.initListData(); // don't forget await here if you're using async
    console.log('data', data)
    if (data.length) {
      this.setState({
        displayArray: data,
        loadMoreVisible: data.length >= 15, // no need for ternary
        currentPage: 2
      });
    }
  }

  render() {
    console.log('this is displayArray = ', this.state.displayArray );
       
    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>
      );
    }
  }
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 (this.props.data != null) {
      console.log('this.props.data =', this.props.data) // OK 
      let productData = await getProduct(this.props.data);
      console.log('productData =', productData )
    }    
  };

  

  async componentDidMount() {
    const data = await this.initListData(); // don't forget await here if you're using async
    console.log('data', data)
    if (data.length) {
      this.setState({
        displayArray: data,
        loadMoreVisible: data.length >= 15, // no need for ternary
        currentPage: 2
      });
    }
    return data;
  }
  

  render() {
    console.log('this is displayArray = ', this.state.displayArray);
       
    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>
      );
    }
  }