【问题标题】:Passing a prop from a Parent component becomes null in the Child component React从 Parent 组件传递一个 prop 在子组件 React 中变为 null
【发布时间】:2021-01-27 13:29:20
【问题描述】:

我正在制作一个简单的 React 站点,它从 API (this API) 获取一些数据,然后将其显示在页面上。我使用的端点是skyblock/auctions 端点。这返回的是一个对象列表,我想获取其中的第一个,然后将其传递给子组件。父母可以成功获取数据,但是当我将它传递给孩子和console.log 它时,它返回null。我能想到它这样做的唯一原因是因为父组件还没有完成获取数据,但我不知道如何让它只在完成后渲染。

这里是父组件AuctionViewer的代码:

class AuctionViewer extends Component {
  state = { data: null}

  loadData = async () => {
    let url = "https://api.hypixel.net/skyblock/auctions?key=INSERT_KET_HERE" 
    let response = await fetch(url);
    let json = await response.json();

    this.setState({data: json.auctions[0]}, function () {
      console.log(this.state.data)
    });
  }

  componentDidMount() {
    this.loadData();
    setInterval(this.loadData, 60 * 1000);
  }

  render() { 
    return (<Auction data={this.state.data} />);
  }
}

这里是子组件Auction

class Auction extends Component {
  state = {
    loading: true,

    item: null,
    price: null,
    startPrice: null,
    time: null,
  };

  loadData() {
    let data = this.props.data;
    console.log(data);

    let end = new Date(data.end - Date.now());
    let timeLeft = end.getHours() + ":" + end.getMinutes() + ":" + end.getSeconds();     
    this.setState({loading: false, item: data.item_name, price: data.highest_bid_amount, startPrice: data.starting_bid, time: timeLeft, timestamp: end});
  };

  componentDidMount() {
    this.loadData();
  }

  render() {
    return (
      <div className="gridBox">
        {this.state.loading ? (
          <p>Loading...</p>
        ) : (
          <div>
            <p>Item: {this.state.item}</p>
            <p>Top Bid: {this.state.price}</p>
            <p>Start Bid: {this.state.startPrice}</p>
            <p>Time Left: {this.state.time}</p>
          </div>
        )}
        <button onClick={this.loadData}>Refresh</button>
      </div>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    我能想到它这样做的唯一原因是因为父组件还没有完成数据的获取......

    没错。

    ...但我不知道如何让它只在完成后渲染。

    你有两个选择:

    1. (我不认为你想要这个。) 将 ajax 调用移到父组件的父组件中,只有当你有数据时才渲染父组件。

    2. 让父组件呈现某种“加载”状态,直到数据可用

    #2 看起来像这样:

    render() { 
      const { data } = this.state;
      return (data ? <Auction data={data} /> : <em>Loading...</em>);
    }
    

    ...但可能比&lt;em&gt;Loading...&lt;/em&gt; 更有吸引力。 :-)

    【讨论】:

      【解决方案2】:

      最简单的是在AuctionViewer“获取”数据时进行一些条件渲染。初始状态为null,并将其传递给Auction,但您可以在等待时有条件地渲染其他 UI 或 null。

      render() { 
        const { data } = this.state;
        return data ? (
          <Auction data={data} />
        ) : <div>Loading...</div>;
      }
      

      或者返回 null 表示不应该渲染任何内容。

      render() { 
        const { data } = this.state;
        return data ? (
          <Auction data={data} />
        ) : null;
      }
      

      【讨论】:

        猜你喜欢
        • 2021-10-15
        • 2018-04-26
        • 2023-01-30
        • 1970-01-01
        • 1970-01-01
        • 2018-09-29
        • 2022-07-12
        • 2022-08-17
        • 2020-08-05
        相关资源
        最近更新 更多