首页 文章

React中的双重渲染与componentDidMount中的异步调用导致错误

提问于
浏览
0

我正在构建一个包含文章索引页面的博客应用程序,您可以从那里单击文章以查看文章或编辑文章 .

如果您从索引页面转到编辑页面,它的工作正常,因为我已经拥有州内的所有文章 . 但是如果我在转到编辑文章页面后刷新,我就不再拥有州内的所有文章了 .

这是一个问题,因为我正在我的编辑文章页面的componentDidMount中进行异步recieveSingleArticle调用,然后我setState,所以我的表单已预先填充 . 有一个双重渲染导致“未捕获的TypeError:无法读取未定义的属性' Headers '错误,可能是在文章被收到状态之前的第一次渲染期间 .

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)”中包装我的异步调用,但这不起作用 . 有没有最好的方法来处理这类问题?任何建议非常感谢!

UPDATE:

另一个有效的解决方案是除componentDidMount外还有一个componentDidUpdate . 如果this.props.article存在则检入componentDidMount,如果存在,则检查setState . 在componentDidUpdate中,将setState包装在以下条件中:

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

1 回答

  • 1

    在调用异步操作之前,只需检查文章是否存在于props中

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

    由于您没有从此方法获得任何渲染,这意味着尚未在生命周期方法 componnetDidMount 中获取道具 . 所以你可以像这样使用 componentWillReceiveProps

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

相关问题