【问题标题】:React js State Object is not recognized within the render method在渲染方法中无法识别 React js 状态对象
【发布时间】:2020-09-07 12:05:51
【问题描述】:

我是 React 的初学者,在 componentDidMount 中,我从 Axios 检索一个响应对象,然后我将它设置为状态对象,即使它可以从外部函数访问,但它在render 方法,不知道怎么绑定状态才能访问render()

弹出的错误:未处理的拒绝(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);
    }
  }
}


非常感谢您的帮助

【问题讨论】:

  • 将有助于显示有问题的代码。顺便说一句,您将this.props.comicData 分配给issueObjectState。这是为什么呢?
  • 你能检查你的api数据来了吗?
  • 是的,我安慰了它,它有效

标签: javascript reactjs


【解决方案1】:

我看到你的代码有很多错误,首先是在构造函数方法之外声明状态,所以你应该先这样做:

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

那么生命周期方法不能与之前的 async 关键字一起使用,你的 async 函数必须在生命周期方法中。

【讨论】:

    【解决方案2】:

    我认为你必须将 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);
    
     }
    }
    

    【讨论】:

      【解决方案3】:

      在将对象分配给issueObjectState 之前,您正尝试访问对象this.state.issueObjectState.imageref。在出现错误时,issueObjectState 只是 ""

      render 在 componentDidMount 之前被调用。您可以改为使用 componentWillMount 将对象分配给issueObjectState。但最好的做法是一起避免 componentWillMount,也许在你的情况下,只需为它分配一个值为 null 的对象

      【讨论】:

        【解决方案4】:

        像这样使用它:

           <img src={this.state.issueObjectState!==""?
            this.state.issueObjectState.imageref : this.state.issueObjectState }
            alt="Image Description" className="mx-auto img-fluid"/>
        

        【讨论】:

          【解决方案5】:

          您的组件中有几个缺陷。

          1. 在获取数据并将其存储到状态之前,您正在渲染方法中访问状态。 Axios 异步获取数据,在 render 方法的初始调用中将不可用。最好在访问状态数据之前添加检查。

          2. 您没有从不正确的渲染方法返回任何元素或组件。

          如下重构渲染部分应该可以工作:

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

          【讨论】:

            【解决方案6】:
            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);
                }
              }
            }
            

            应该是:

            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
                    }
            });
            
                  }
                }
            

            和:

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

            渲染:

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

            或:

            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
            }
            

            【讨论】:

              猜你喜欢
              • 2018-05-01
              • 2018-04-12
              • 2021-08-09
              • 2018-10-04
              • 2018-08-24
              • 1970-01-01
              • 1970-01-01
              • 2018-06-03
              • 1970-01-01
              相关资源
              最近更新 更多