Есть ли способ использовать ключевое слово await внутри рендера в коде React? - PullRequest
1 голос
/ 31 мая 2019

Я пытаюсь использовать интерфейс субстрата для отображения функций, доступных в моем модуле времени выполнения. Код написан на React. Я пытаюсь создать компонент, который поможет мне отслеживать все предыдущие состояния структуры.

Вызов runtime.template.assets(i) принимает в качестве входных данных шестнадцатеричное значение i и возвращает структуру kitty с ключом parent_hash (имеющим шестнадцатеричное значение). Я хочу, чтобы цикл while выполнялся до тех пор, пока не достигну специального шестнадцатеричного значения, которое в данном случае равно "0x11da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be9", которое я преобразовал в String для достижения условия завершения.

Пожалуйста, игнорируйте тег <KittyShrieks>, потому что я использую его для отображения некоторых значений в пользовательском интерфейсе. По сути, я не могу сделать это внутри цикла 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. Итак, проблема в том, что пользовательский интерфейс не загружается, и я получаю следующую ошибку:

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); и вставляю оператор break в конце цикла. Поэтому я не могу повторять цикл.

Я новичок в React и даже в Javascript в целом. Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 31 мая 2019

Компонент всегда должен иметь возможность что-то визуализировать (или null). Здесь вы фактически просите React отрендерить 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...