为什么 Appbase 在返回正确的项目之前返回“未定义”?

IT技术 javascript reactjs
2021-05-21 18:21:50

我正在使用 AppBase.io 作为数据库,但我不明白为什么这个组件在获得一个项目后会呈现两次?似乎 AppBase“数据库”首先返回未定义然后返回正确的项目有人知道为什么吗?查看示例,我在其中获得了 2 个日志。

在这个组件中,我需要从数据库中获取一个项目并呈现它(没什么特别的)。

谢谢解释。

var appbaseRef = new Appbase({
  url: "https://JHtFTzy4H:d083068b-596c-489d-9244-8db2ed316e79@scalr.api.appbase.io",
  app: "winwin"
});


class ItemFull extends React.Component {
  constructor() {
    super();
    this.state = {
      item: ''
    }
  }

  componentWillMount() {
    appbaseRef.get({
      type: "items",
      id: 'AWI5K7Q-5Q83Zq9GZnED'
    }).on('data', (response) => {
      this.setState({
        item: response
      });

    }).on('error', function(error) {
      console.log(error)
    })
  }

  render() {
    console.log(this.state.item._id, '<-- console_log');
    return (<div></div>);
  }
}

ReactDOM.render(<ItemFull /> , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/appbase-js/2.2.11/appbase.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

2个回答

它没有。您在开始异步调用componentWillMount不托起渲染过程(这是好的),所以render在调用完成之前调用,因此this.state.item._idundefined因为在这一点上,this.state.item''(你在构造函数中设置的值)。

这是完全正常的,只要确保在组件还没有信息时以适当的方式呈现组件,例如:

如果在您获得该信息之前根本不应该呈现该组件,那么您在错误的位置请求它。:-) 您会在父组件中请求它,并且只有在您拥有信息(在 中传递信息props时才呈现此组件,如下所示:

那是因为appbaseRef.get是异步的。ItemFull做它的初始渲染,你首先看到console.log

this.state.item._id第一次实际检查_id字符串对象(“”),这当然是未定义的。

然后this.setState被调用componentWillMount(它至少已经被挂载和渲染过一次)并更新状态,因为状态改变迫使组件重新渲染。

这就是您看到 2 个控制台日志的原因。

您无法阻止render()钩子执行,但您可以确保仅在数据到达时才呈现您的内容:

render() {
  console.log(this.state.item._id, '<-- console_log');

  if(this.state.item) { // this will check if item is different than ''
    return ( 
      <div> 

      </div>
    )
  }
}

还有一件事。使用componentDidMount初始数据获取,因为它是推荐的地方。