Есть ли способ использовать ключевое слово await внутри рендера в коде React?
Я пытаюсь использовать интерфейс субстрата для отображения функций, доступных в моем модуле времени выполнения. Код написан на 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 ответ
Компонент всегда должен уметь что-то отображать (или 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
завершить.