Javascript reactjs在构造函数vs属性中存储状态

Javascript reactjs在构造函数vs属性中存储状态,javascript,reactjs,Javascript,Reactjs,我有一个非常简单的react组件,它需要连接到API并检索一些JSON数据,然后用于显示一些信息 在下面的类/组件中,我将挂载和状态作为属性。我通常使用构造函数来保存状态,但在这种情况下,如果我将状态移动到构造函数,我似乎无法访问渲染器中的数据(projectInfo)。在渲染器内部(包含{projectInfo.name}的行),我得到错误:TypeError:无法读取null的属性“name” 如何使用此类中的构造函数来保存状态?为什么下面的类在我使用构造函数时不起作用?处理这种事情的惯例是

我有一个非常简单的react组件,它需要连接到API并检索一些JSON数据,然后用于显示一些信息

在下面的类/组件中,我将
挂载
状态
作为属性。我通常使用构造函数来保存状态,但在这种情况下,如果我将状态移动到构造函数,我似乎无法访问渲染器中的数据(
projectInfo
)。在渲染器内部(包含
{projectInfo.name}
的行),我得到错误:TypeError:无法读取null的属性“name”

如何使用此类中的构造函数来保存状态?为什么下面的类在我使用构造函数时不起作用?处理这种事情的惯例是什么

class MyReportSummary extends Component {
  mounted = true;
  state = {
    projectInfo: null,
    isLoading: true,
    error: null
  };

  componentDidMount() {
    fetch(`/api/projects/${this.props.projectId}`)
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          throw new Error("Encountered problem fetching project info");
        }
      })
      .then(data => {
        if (this.mounted) {
          this.setState({
            projectInfo: data
          });
        }
      })
      .catch(fetchError => {
        if (this.mounted) {
          this.setState({
            isLoading: false,
            error: fetchError
          });
        }
      });
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  render() {
    const { isLoading, error, projectInfo } = this.state;

    if (error) {
      return <p>{error.message}</p>;
    }

    if (isLoading) {
      return <p>Loading...</p>;
    }

    return (
      <div className="myReportSummary">
        Summary of Project name: {projectInfo.name}
        Number of events: {this.props.data.length}
      </div>
    );
  }
}

国家的正确公约是什么?
constructor
不是正确的方法吗?

像第二个示例一样初始化构造函数中的状态是完全有效的,但是两个示例不一样。在类属性版本中将
isLoading
设置为
true
,但在构造函数中将
isLoading
设置为
false

如果
null
中的
error
isLoading
false
,您将点击渲染方法的最后一部分。由于在您的请求完成之前,
projectInfo
null
,因此您将尝试在
null
上访问
name
,并获取错误信息

isLoading
设置为
true
,它应该可以按预期工作,甚至可以将
projectInfo
设置为空对象
{}
,但这样您就不会得到加载指示器

class MyReportSummary extends Component {
  constructor(props) {
    super(props);

    this.mounted = true;
    this.state = {
      projectInfo: {},
      isLoading: true,
      error: null
    };
  }

  // ...
}

您缺少
构造函数
函数,您需要在构造函数中初始化
这个。状态
。@Hoyen调用了它,它是完全有效的。这是因为它试图在获取承诺完成之前进行渲染,访问默认
null
对象上的
.name
。将默认的
状态.projectInfo
设置为空对象
{}
,您应该会没事的。感谢@Tholle提供的示例和您迄今为止的帮助。我更新了这个问题的描述。我希望这能澄清我的问题。@aver啊,现在我看到了错误。您正在将
isLoading
初始化为false。如果
null
中的
error
isLoading
false
,则将点击渲染方法的最后一部分。由于在您的请求完成之前,
projectInfo
null
,因此您将尝试在
null
上访问
name
,并获取错误信息。将
isLoading
设置为
true
,它应该可以按预期工作,甚至可以将
projectInfo
设置为空对象
{}
,但这样您就不会得到
加载…
。就是这样!!非常感谢你的帮助。我不知道加载标志导致了所有问题。@aver不客气!这发生在我们所有人身上。很容易错过那些东西
class MyReportSummary extends Component {
  constructor(props) {
    super(props);

    this.mounted = true;
    this.state = {
      projectInfo: {},
      isLoading: true,
      error: null
    };
  }

  // ...
}