React state 似乎没有在渲染前获取 api 并设置状态

发布于 2025-01-19 00:02:16 字数 2204 浏览 0 评论 0原文

我正在尝试获取报价 api 并使用第一个报价填充反应组件。稍后我将使用该按钮随机选择一个。我现在刚刚学习 React,我在 freecodecamp 中的 React 教程没有显示任何有关 fetch 的内容,所以我找到了在线提取这些引用的代码。如果我在 this.setState 之后添加另一个回调,我可以 console.log 并查看所有数组,但即使在渲染中使用 if 语句,它似乎也不存在于要渲染的状态中。关于设置状态或在状态设置为数组后渲染组件,我缺少什么。我已经看过这个 stackoverflow 问题

class Quotes extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      quotes: []
    }
  }
  
  componentDidMount() {
      fetch("https://type.fit/api/quotes")
      .then((response) => response.json())
      .then(quotesList => {
          this.setState({ quotes: quotesList });
      });
  }
  
  render(){ 
    if (!this.state.quotes) {
            return <div />
        }
    
    return(
      <div>
        <p id="text">{this.state.quotes[0].text}</p>
        <p id="author">{this.state.quotes[0].author}</p>
        <div id="buttons">
          <button id="new-quote">New Quote</button>
          <a id="tweet-quote" href="#"><i className="fa-brands fa-twitter"></i></a>
        </div>
      </div>
    );
  }
}

class QuoteBox extends React.Component{
  constructor(props){
    super(props)
  }
  
  render(){
    return(
      <div id="quote-box">
         <Quotes />
      </div>
      
    );
  } 
}

ReactDOM.render(<QuoteBox />, document.getElementById('page-wrapper'))
#page-wrapper{
  
  #quote-box{
    display:flex;
    height:100vh;
    justify-content:center;
    align-items:center;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="page-wrapper">
  
</div>

I'm trying to fetch an api of quotes and populate the react component with the first one. Later I'll use the button to pick a random one. I'm just now learning react, my react tutorial in freecodecamp didn't show anything about fetch so I found the code to pull these quotes online. If I add another callback after the this.setState I can console.log and see all the arrays but even with the if statement in the render it doesn't seem to be there in the state to render. What am I missing about setting the state or getting the component to render after the state has set to the array. I have already looked at this stackoverflow question.

class Quotes extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      quotes: []
    }
  }
  
  componentDidMount() {
      fetch("https://type.fit/api/quotes")
      .then((response) => response.json())
      .then(quotesList => {
          this.setState({ quotes: quotesList });
      });
  }
  
  render(){ 
    if (!this.state.quotes) {
            return <div />
        }
    
    return(
      <div>
        <p id="text">{this.state.quotes[0].text}</p>
        <p id="author">{this.state.quotes[0].author}</p>
        <div id="buttons">
          <button id="new-quote">New Quote</button>
          <a id="tweet-quote" href="#"><i className="fa-brands fa-twitter"></i></a>
        </div>
      </div>
    );
  }
}

class QuoteBox extends React.Component{
  constructor(props){
    super(props)
  }
  
  render(){
    return(
      <div id="quote-box">
         <Quotes />
      </div>
      
    );
  } 
}

ReactDOM.render(<QuoteBox />, document.getElementById('page-wrapper'))
#page-wrapper{
  
  #quote-box{
    display:flex;
    height:100vh;
    justify-content:center;
    align-items:center;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="page-wrapper">
  
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滥情空心 2025-01-26 00:02:16

空数组 [] 不是假值,因此您的 if 不会被触发,并且会完成越界数组访问。检查 if 中的数组长度,它将起作用。

请参阅 StackOverflow 上的此线程,其中涵盖真值和假值。

这里你的代码与 if 内的条件更改为
this.state.quotes.length === 0

class Quotes extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      quotes: [],
    };
  }

  componentDidMount() {
    fetch("https://type.fit/api/quotes")
      .then((response) => response.json())
      .then((quotesList) => {
        this.setState({ quotes: quotesList });
      });
  }

  render() {
    // check for array length here
    if (this.state.quotes.length === 0) {
      return <div>Fetching data...</div>;
    }

    return (
      <div>
        <p id="text">{this.state.quotes[0].text}</p>
        <p id="author">{this.state.quotes[0].author}</p>
        <div id="buttons">
          <button id="new-quote">New Quote</button>
          <a id="tweet-quote" href="#">
            <i className="fa-brands fa-twitter"></i>
          </a>
        </div>
      </div>
    );
  }
}

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

  render() {
    return (
      <div id="quote-box">
        <Quotes />
      </div>
    );
  }
}

ReactDOM.render(<QuoteBox />, document.getElementById("page-wrapper"));
#page-wrapper{
  
  #quote-box{
    display:flex;
    height:100vh;
    justify-content:center;
    align-items:center;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="page-wrapper">
  
</div>

An empty array [] is not a falsy value, consequently your if does not get triggered and an out of bounds array access is done. Check for array length in your if instead and it will work.

See this thread on StackOverflow which covers truthy and falsy values.

Here your code with the condition within the if changed to
this.state.quotes.length === 0.

class Quotes extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      quotes: [],
    };
  }

  componentDidMount() {
    fetch("https://type.fit/api/quotes")
      .then((response) => response.json())
      .then((quotesList) => {
        this.setState({ quotes: quotesList });
      });
  }

  render() {
    // check for array length here
    if (this.state.quotes.length === 0) {
      return <div>Fetching data...</div>;
    }

    return (
      <div>
        <p id="text">{this.state.quotes[0].text}</p>
        <p id="author">{this.state.quotes[0].author}</p>
        <div id="buttons">
          <button id="new-quote">New Quote</button>
          <a id="tweet-quote" href="#">
            <i className="fa-brands fa-twitter"></i>
          </a>
        </div>
      </div>
    );
  }
}

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

  render() {
    return (
      <div id="quote-box">
        <Quotes />
      </div>
    );
  }
}

ReactDOM.render(<QuoteBox />, document.getElementById("page-wrapper"));
#page-wrapper{
  
  #quote-box{
    display:flex;
    height:100vh;
    justify-content:center;
    align-items:center;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="page-wrapper">
  
</div>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文