首页 > 解决方案 > 有没有办法在 React 代码的渲染中使用 await 关键字

问题描述

我正在尝试使用 Substrate UI 来显示我的运行时模块中可用的功能。代码是用 React 编写的。我正在尝试创建一个组件来帮助我跟踪结构的所有先前状态。

runtime.template.assets(i)调用将十六进制值i作为输入并返回kitty具有键parent_hash(具有十六进制值)的结构。我希望while循环执行,直到我达到一个特殊的十六进制值,在这种情况下"0x11da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9",我已经转换String为实现终止条件。

请忽略该<KittyShrieks>标签,因为它是我用来在 UI 中显示某些值的东西。基本上我无法在 while 循环中执行此操作

var kitty = await runtime.template.kitties(i);
.
.
i = kitty.parent_hash;

所需代码

export class TrackCards extends ReactiveComponent {
    constructor(props) {
        super(['hash'])

    }


    unreadyRender() {
        return <span>Nothing to track</span>
    }
    async readyRender() {
      let kitties = [];
        var i = this.state.hash;
        var root_hash = "0x11da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9";
        var root = "17,218,109,31,118,29,223,155,219,76,157,110,83,3,235,212,31,97,133,141,10,86,71,161,167,191,224,137,191,146,27,233";
        var iter = 0;
        var a;

        while ((root != i.toString())  {


          var kitty = await runtime.template.kitties(i);
          kitties.push(
              <div className="column" key={i}>

                  <KittyShrieks
                  owner_count = {runtime.template.kittyHistoryCount(i)}
                  hash_original = {this.state.hash}
                  />
              </div>
          );
          i = kitty.parent_hash;
        }
        return <div className="ui stackable six column grid">{kitties}</div>;
    }
}

我不认为使用异步渲染是一个有效的事情,但我这样做是因为我似乎别无选择,只能使用await keyword. 所以,问题是 UI 没有加载,我收到以下错误:

Uncaught Invariant Violation: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

如果我删除async关键字、语句并在循环末尾var kitty = await runtime.template.kitties(i);插入语句,则 UI 加载正常。break因此,不允许我遍历循环。

总的来说,我对 React 甚至 Javascript 都是陌生的。任何形式的帮助将不胜感激。

标签: javascriptreactjssubstrate

解决方案


组件总是需要能够渲染某些东西(或null)。在这里,您实际上是在要求 React 渲染 a promise,因此您的错误。

您应该将此逻辑提取到componentDidMount()生命周期中。以您的代码为例,它可能如下所示:

export class TrackCards extends ReactiveComponent {
  constructor(props) {
      super(['hash'])

      this.state = {
        kitties: []
      }
  }

  async componentDidMount() {
    const kitties = [];
    var i = this.state.hash;
    var root_hash = "0x11da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9";
    var root = "17,218,109,31,118,29,223,155,219,76,157,110,83,3,235,212,31,97,133,141,10,86,71,161,167,191,224,137,191,146,27,233";
    var iter = 0;
    var a;

    while (root != i.toString())  {
      var kitty = await runtime.template.kitties(i);
      kitties.push(
          <div className="column" key={i}>
              <KittyShrieks
              owner_count = {runtime.template.kittyHistoryCount(i)}
              hash_original = {this.state.hash}
              />
          </div>
      );
      i = kitty.parent_hash;
    }
    this.setState(
      kitties
    );
  }

  render () {
    const { kitties } = this.state;
    return (
      kitties.length 
        ? <div className="ui stackable six column grid">{kitties}</div>
        : <span>Nothing to track</span>
    )
  }
}

我们最初正在返回<span>Nothing to track</span>,而您正在等待kitties完成。


推荐阅读