简体   繁体   English

在渲染方法中无法识别 React js 状态对象

[英]React js State Object is not recognized within the render method

I'm a beginner in React, in the componentDidMount, I'm retrieving a response object from Axios then I'm setting it to the state object, even though it is accessible from outside functions it wouldn't work inside the render method, I don't know how to bind the state to get access to render()我是 React 的初学者,在 componentDidMount 中,我正在从 Axios 检索响应对象,然后将其设置为状态对象,即使它可以从外部函数访问,但它在渲染方法中不起作用,我不知道如何绑定状态以访问 render()

error that pops: Unhandled Rejection (TypeError): Cannot read property 'imageref' of undefined弹出的错误:未处理的拒绝(TypeError):无法读取未定义的属性“imageref”

export default class Product extends Component {
  constructor(props) {
    super(props);
    const id = this.state.comicId;
    console.log("This is printed from the constructor " + id);
  }

  state = {
    comicId: "",
    issueObjectState: "",
  };
render(){
<img
 src={this.state.issueObjectState.imageref}
 alt="Image Description"
 className="mx-auto img-fluid"/>
}
 
async componentDidMount() {
    let state = [];
    const id = this.props.location;
    let comicId = id.data;
    this.setState({ comicId: this.props.comicId });

    let issueData = await axios.get(`http://localhost:5000/comic/${comicId}`);
    let comicData = issueData.data;

    if (comicData) {
      this.setState({ issueObjectState: comicData });
      console.log(this.state.issueObjectState);
    }
  }
}


help is much appreciated非常感谢帮助

I see that you have many errors on your code, starting with declaring the state outside the constructor method, so you should do this first :我看到你的代码有很多错误,首先是在构造函数方法之外声明状态,所以你应该先这样做:

constructor(props) {
super(props);
this.state = {
comicId: "",
issueObjectState: "",
};
}

then lifecycle methodes can't be used with the async keyword before it, your async function must be inside the lifecycle method.那么生命周期方法不能与之前的 async 关键字一起使用,您的异步函数必须在生命周期方法内。

What I believe here is you have to shift your this.state object to the constructor.我在这里相信你必须将你的this.state对象转移到构造函数。

export default class Product extends Component {
 constructor(props) {
  super(props);
  state = {
    comicId: "",
    issueObjectState: "",
  };
  const id = this.state.comicId;
  console.log("This is printed from the constructor " + id);

 }
}

You are trying to access the object this.state.issueObjectState.imageref before you assign an object to issueObjectState .在将对象分配给this.state.issueObjectState.imageref之前,您正在尝试访问对象issueObjectState At the time of the error the issueObjectState is simply ""在错误发生时, issueObjectState只是""

render is called before componentDidMount. render在 componentDidMount 之前调用。 What you could use instead is componentWillMount to assign an object to issueObjectState .您可以使用 componentWillMount 将对象分配给issueObjectState But it would be best practice to avoid componentWillMount alltogether and maybe in your case just assign it an object with a value of null但是最好的做法是完全避免 componentWillMount ,也许在您的情况下,只需为其分配一个值为 null 的对象

Several flaws in your component.您的组件中有几个缺陷。

  1. You are accessing state inside the render method before the data is fetched and stored to the state.在获取数据并将其存储到状态之前,您正在访问渲染方法中的状态。 Axios fetch the data asynchronously and it won't be available inside the initial call of render method. Axios 异步获取数据,并且它在 render 方法的初始调用中不可用。 Better add a check before accessing state data.最好在访问状态数据之前添加检查。

  2. You are not returning any element or component from the render method which is incorrect.您没有从 render 方法返回任何不正确的元素或组件。

Refactoring the render part as bellow should work:如下重构渲染部分应该可以工作:

render(){
 return (
 this.state.issueObjectState == '' ? null : 
 <img
  src={this.state.issueObjectState.imageref}
  alt="Image Description"
  className="mx-auto img-fluid"/>
 )
}

Use it like :像这样使用它:

   <img src={this.state.issueObjectState!==""?
    this.state.issueObjectState.imageref : this.state.issueObjectState }
    alt="Image Description" className="mx-auto img-fluid"/>
async componentDidMount() {
    let state = [];
    const id = this.props.location;
    let comicId = id.data;
    this.setState({ comicId: this.props.comicId });

    let issueData = await axios.get(`http://localhost:5000/comic/${comicId}`);
    let comicData = issueData.data;

    if (comicData) {
      this.setState({ issueObjectState: comicData });
      console.log(this.state.issueObjectState);
    }
  }
}

should be:应该:

componentDidMount() {
    const  {comicId} = this.state

    axios.get(`http://localhost:5000/comic/${comicId}`).then((issueData)=> {
      this.setState({ issueObjectState: issueData.data ? issueData.data : null });
      //console.log(this.state.issueObjectState); <-- does not work this.setState is like async
        }
});

      }
    }

and:和:

constructor(props) {
  super(props);
  this.state = {
   comicId: props.location.data,
   issueObjectState: "",
};
}

render:使成为:

render(){
 return (
  <div>
    {this.state.issueObjectState &&
    <img
      src={this.state.issueObjectState.imageref}
      alt="Image Description"
      className="mx-auto img-fluid"/>
    }
  </div>
 )
}

or:或者:

render(){
 if (this.state.issueObjectState) 
 return (
    <img
      src={this.state.issueObjectState.imageref}
      alt="Image Description"
      className="mx-auto img-fluid"/>
 )
 return <Loading />  //<--- a compenent that show an animated loading image
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM