Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用componentDidMount中的异步调用在React中进行双重呈现导致错误_Javascript_Reactjs - Fatal编程技术网

Javascript 使用componentDidMount中的异步调用在React中进行双重呈现导致错误

Javascript 使用componentDidMount中的异步调用在React中进行双重呈现导致错误,javascript,reactjs,Javascript,Reactjs,我正在构建一个博客应用程序,它有一个文章索引页面,从那里你可以点击一篇文章来查看文章或编辑文章 如果你从索引页转到编辑页,效果很好,因为我已经把所有的文章都放在状态了。但是,如果我在进入编辑文章页面后刷新,我将不再拥有所有处于状态的文章 这是一个问题,因为我正在编辑文章页面的componentDidMount中进行异步ReceiveSingleArticle调用,然后我设置了State,以便预先填充表单。有一个双重呈现导致“UncaughtTypeError:Cannotreadproperty

我正在构建一个博客应用程序,它有一个文章索引页面,从那里你可以点击一篇文章来查看文章或编辑文章

如果你从索引页转到编辑页,效果很好,因为我已经把所有的文章都放在状态了。但是,如果我在进入编辑文章页面后刷新,我将不再拥有所有处于状态的文章

这是一个问题,因为我正在编辑文章页面的componentDidMount中进行异步ReceiveSingleArticle调用,然后我设置了State,以便预先填充表单。有一个双重呈现导致“UncaughtTypeError:Cannotreadproperty'title'of undefined”错误,可能是在文章接收到状态之前的第一次呈现期间

class ArticleEdit extends React.Component {
  constructor(props) {
    super(props);

    this.state = {title: "", body: "", imageFile: ""};

    this.handleChange = this.handleChange.bind(this);
    this.handlePublish = this.handlePublish.bind(this);
    this.handleFile = this.handleFile.bind(this);
    this.handleCancel = this.handleCancel.bind(this);
  }

  componentDidMount() {
    const { article, requestSingleArticle } = this.props;

    requestSingleArticle(this.props.match.params.articleID)
    .then(() => {
      this.setState({
        title: article.title,
        body: article.body,
        imageFile: article.imageFile
      });
    });
  }
...
我尝试将异步调用包装在“if(this.props.article)”中,但没有成功。有没有处理这类问题的最佳方法?非常感谢您的建议

更新:

另一个有效的解决方案是除了componentDidMount之外还有一个componentDidUpdate。如果this.props.article存在,请签入componentDidMount,如果存在,请设置状态。在componentDidUpdate中,将setState包装为以下条件:

if (!prevProps.article && this.props.article)

在调用异步操作之前,只需检查道具中是否有文章

componentDidMount() {
  const { article, requestSingleArticle } = this.props;
  if (!(article && requestSingleArticle)) return; // this line
  requestSingleArticle(this.props.match.params.articleID)
  .then(() => {
    this.setState({
      title: article.title,
      body: article.body,
      imageFile: article.imageFile
    });
  });
}
由于您没有从该方法获得任何渲染,这意味着在生命周期方法
componendidmount
中尚未获得道具。因此,您可以像这样使用
组件willreceiveprops

componentWillReceiveProps(nextProp) {
  // this line here will check the article props' status so that
  // we will not use setState each time we get a prop
  if (this.props.article === nextProp.article) return;

  // rest is just the same code from above
  const { article, requestSingleArticle } = nextProp;
  if (!(article && requestSingleArticle)) return; // this line
  requestSingleArticle(this.props.match.params.articleID)
  .then(() => {
    this.setState({
      title: article.title,
      body: article.body,
      imageFile: article.imageFile
    });
  });
}

尝试将API调用移动到
构造函数
;)你可能正在使用路由器吗?将id作为道具从ArticleList传递到ArticleEdit。当您刷新(浏览器)编辑页面时,将不会获取任何数据?。如果是这样的话,那么作为道具传递的文章id将为null,因此http请求将失败,这要感谢你们两个!添加到我的构造函数中确实起到了作用。不幸的是,使用此方法,如果您从ArticleEdit页面中刷新页面,它不会预填充表单。这是因为当您的组件刚刚装入时,您的道具中没有文章。我认为您应该使用
componentWillReceiveProps,而不是
componentDidMount
。这样,如果文章道具肯定在组件的生命周期内,那么您一定会得到它。啊,组件将收到道具工作!我想我可能会考虑在我移动时考虑GETPREDATESTOFF道具。forward@akorn3000如果是那样的话,请把答案标记为正确!让其他面临同样问题的人知道什么能解决他们的问题:)