1

我一直在尝试通过状态将 API 调用获得的数据发送到子组件,但它似乎不起作用。

我一直将对象的每个单独属性作为道具发送给子组件。

有没有办法将整个 JSON 响应作为道具发送给子组件?

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: {},
      name: ""
    };
  }
  componentWillMount() {
    this.getWeather();
  }
  getWeather(city) {
    fetch(
      `https://api.apixu.com/v1/current.json?key=2da827a3ce074ddb85417374xxxxxx&q=paris`
    )
      .then(res => res.json())
      .then(data => {
        this.getData(data);
      })
      .catch(err => {
        return Promise.reject();
      });
  }
  getData(data) {
    var location = data.location.name;

    this.setState({ data: data, name: location });
    console.log(this.state.name);
    console.log(this.state.data);
  }
  render() {
    return <Child name={this.state.name} data={this.state.data} />;
  }
}

class Child extends React.Component {
  render() {
    var data = this.props.data;
    return (
      <div>
        <h1>{this.props.name}</h1>
        <h1> {data.current.cloud}</h1>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById("root"));

我希望数据对象也被传递给孩子,但它没有,我得到一个崩溃屏幕,指出数据对象未定义。

有没有办法将 API 调用中获得的整个 JSON 作为道具发送给子组件?

4

3 回答 3

1

您的Child组件将在getWeatherapi 返回数据之前呈现。所以this.props.dataChild组件中{},当你访问时应用程序崩溃data.current.cloud

您需要检查它是否data不为空并且它具有current属性。所以你的代码应该是

class Child extends React.Component {
  render() {
    var data = this.props.data;
    return (
      <div>
        <h1>{this.props.name}</h1>
        <h1>{data && data.current ? data.current.cloud : ''}</h1>
      </div>
    );
  }
}
于 2019-07-31T04:07:43.063 回答
1

在方法“ ComponentDidMount ”而不是“ComponentWillMount”中执行所有 API 调用始终是最佳实践。这将取消您检查响应是否来自 API。一旦响应到来,组件将被重新渲染。所以,你可以像下面这样

componentDidMount() {
        this.getWeather();
      }
于 2019-07-31T04:30:57.250 回答
1

作为@tien Duoung 评论的补充,

您可能想要添加一个额外的状态变量。您可以调用它fetchingloading. 目的是至少在您的 api 结果尚未准备好时显示一些内容。它可能是这样的:

this.state = { data: {}, name: "", fetching: true }

.then您的getData方法中,一旦 data.current 可用,this.setState({ fetching: false })

getData(data) { var location = data.location.name;

this.setState({ data: data, name: location, fetching: false });
console.log(this.state.name);
console.log(this.state.data);

}

然后将 fetching 作为 prop 传递给子组件,当 fetching 为真时,渲染一个加载器组件或说一个占位符<h1>Loading...</h1>

于 2019-07-31T05:18:00.483 回答