Привет, ребята , это мой первый пост о переполнении стека, но я сделаю все возможное, чтобы придерживаться правильных форматов!Подводя итог, я потратил последние пять часов на этот компонент реагирования, пытаясь отрисовать список объектов, передаваемых из состояния моего родительского компонента, через реквизиты ребенка.Я перепробовал все пути, исследовал несколько решений, но, похоже, ничего не получалось.Это мой первый раз, когда я использую веб-пакет, может быть, есть какой-то плагин, который я должен загрузить для использования React State и реквизитов?Я не знаю.В любом случае, я опубликую фрагменты ниже и опишу каждый шаг в меру своих возможностей.
Приложение для моих родителей
У меня не было проблем с этим, я регистрировал свои результаты каждый шагтаким образом, для факта я знаю, что функция getWeather правильно выбирает данные из API Weatherbit и устанавливает состояние, которое, в свою очередь, как вы увидите, передает массив вchild через его реквизит.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {weatherArray: []}
this.getWeather = this.getWeather.bind(this);
}
getWeather() {
const newWeather = WeatherHelper.inputPrompt();
console.log(newWeather)
this.setState({weatherArray: newWeather})
WeatherHelper.showData()
}
Все еще в приложении "Мой родитель"
Как вы можете видеть, я передаю состояние в качестве подпорки ребенку, который вскоре обновится, как только setState работает
<div id='side-apps'>
<div id='weather-side-app'>
<WeatherApp weatherArray={this.state.weatherArray} />
</div>
</div>
Приложение «Мой ребенок»
Так вот, это становится странным ... Это мой дочерний компонент, и, как вы можете видеть, когдаКомпонент получает новые реквизиты, он сначала проверяет, обновлены ли эти реквизиты.Затем, предполагая, что эти реквизиты являются новыми, метод componentWillReceiveProps установит состояние и выполнит повторную визуализацию соответственно (или вы так думаете).Вы также можете видеть, что я широко использовал протоколирование, чтобы попытаться задокументировать свою проблему, о которой я расскажу ниже.Обратите внимание, что в методе componentWillReceiveProps , если реквизиты отличаются от оригиналов (т. Е. Обновлены), метод будет регистрировать несколько штрихов вокруг обновленных реквизитов, чтобы вы могли указать их (вы увидите).Кстати, я понимаю, что мне даже не нужно было использовать метод componentWillReceiveProps , одной только функции родителей setState должно быть достаточно для обновления моего компонента, но, увы, этого не произошло(и ни один из 10 других способов, которые я пробовал).
class WeatherApp extends React.Component {
constructor(props) {
super(props);
this.state = {currentWeather: []}
}
handleCloseClick() {
WeatherHelper.hideData();
}
componentWillReceiveProps(nextProps) {
if (nextProps.weatherArray !== this.state.currentWeather) {
console.log('---')
console.log(nextProps.weatherArray)
console.log('---')
this.setState({currentWeather: nextProps.weatherArray})
} else {
{console.log("if you see an array under this comment," +
"that means the above if statement read the state's
currentWeather array's length" +
" as zero. EVEN THOUGH the componentWillReceiveProps method" +
" updated and set the state accordingly...")}
console.log(nextProps.weatherArray)
console.log(this.state.currentWeather)
}
}
render() {
if (this.state.currentWeather.length > 0) {
return (
<div class='weatherApp-main'>
<div className='close-sidebar-button'>
<img src='https://i.postimg.cc/hj0rYKxc/close-button.png' onClick={this.handleCloseClick}/>
</div>
<div id='weather-app-header'>
<h2>{this.state.currentWeather}</h2>
<h3></h3>
<h4></h4>
</div>
<div id='weather-app-table'>
</div>
</div>
)
} else {
{console.log(this.state.currentWeather)}
return <p></p>
}
}
}
Сведения о ведении дочерних компонентов
Если вы посмотрите на снимок экрана, вы увидите, что мои записи с моего ребенка componentWillReceiveProps метод доказывает, что функция setState должна была вызвана, но по какой-то причине не обновляет html и отображает данные дочернего элемента.
ведение журнала дочернего компонентаподробности
Сведения о дочерних компонентах
Ладно, последняя вещь ... Я также публикую инструмент Dev Chrome, который показывает, какие компоненты имеют реквизиты и состояния.На этом изображении видно, что дочерний компонент сделал получил нужные реквизиты и соответственно обновил свое состояние. Но, опять же, по какой-то причине он не позволяет мне получить к ним доступ и отобразить результаты
детали реакции дочернего компонента
Я действительно извиняюсь, если этовопрос слишком длинный ... И да, я понимаю, что несколько похожих постов уже решены, но я просмотрел большинство из них, и моя ситуация просто не относится к тому, что я могу сказать ... Я не эксперт, но я не новичок, чтобы реагировать.Это действительно поставило меня в тупик. Заранее большое спасибо за помощь .Я могу предоставить дополнительные скриншоты, фрагменты кода или даже видео, если это поможет !!!
makezi
EDIT
Я добавил замену блока кода функцией карты,и, как вы видите, проблема не в том, как я доставляю данные в DOM.По какой-то причине проблема заключается в том, что мой компонент не читает данные в своем состоянии (я опубликую более подробный снимок экрана, чтобы лучше документировать проблему)
render() {
console.log('++++')
console.log(this.state.currentWeather.length);
if (this.state.currentWeather.length > 0) {
return (
<div class='weatherApp-main'>
<div className='close-sidebar-button'>
<img src='https://i.postimg.cc/hj0rYKxc/close-button.png' onClick={this.handleCloseClick}/>
</div>
<div id='weather-app-header'>
{this.state.currentWeather.map(item => <div><span>{item.city}</span></div>)}
<h3></h3>
<h4></h4>
</div>
<div id='weather-app-table'>
</div>
</div>
)
} else {
{console.log("if you see an array under this comment," +
"that means the above if statement read the state's currentWeather array's length" +
" as zero. EVEN THOUGH the componentWillReceiveProps method" +
" updated and set the state accordingly...")}
{console.log(this.state.currentWeather)}
return <p></p>
}
}
улучшенные подробности регистрации
Второе редактирование комментария Минь Хонга Трона
Я обновил функцию getWeather моего родителя, чтобы она стала асинхронной, а также отредактировал ведение журнала, чтобы оно было более наглядным.Вы можете видеть , хотя массив currentWeather в состоянии имеет 8 объектов, длина по-прежнему читается как ноль! Я не думаю, что проблема заключается в сравнении массивов.По какой-то причине моя функция рендеринга не может прочитать данные в моем состоянии ... или она не обновляется при запуске setState.** вы не можете сказать по скриншоту, но массив nextProps прочитан и полностью зарегистрирован в консоли.хотя после запуска setState '' console.log (this.state.currentWeather) '' записал пустой массив, странно, верно?**
componentWillReceiveProps(nextProps) {
if (nextProps.weatherArray !== this.state.currentWeather) {
console.log("--nextProps weatherArray--")
console.log(nextProps.weatherArray)
console.log('--------------------------')
this.setState({currentWeather: nextProps.weatherArray})
console.log("==child's state==")
console.log(this.state.currentWeather)
console.log("=================")
} else {
console.log(nextProps.weatherArray)
console.log(this.state.currentWeather)
}
}
render() {
console.log("++child's state's length in render method++")
console.log(this.state.currentWeather.length);
console.log("+++++++++++++++++++++++++++++++++++++++++++")
if (this.state.currentWeather.length > 0) {
return (
<div class='weatherApp-main'>
<div className='close-sidebar-button'>
<img src='https://i.postimg.cc/hj0rYKxc/close-button.png' onClick={this.handleCloseClick}/>
</div>
<div id='weather-app-header'>
{this.state.currentWeather.map(item => <div><span>{item.city}</span></div>)}
<h3></h3>
<h4></h4>
</div>
<div id='weather-app-table'>
</div>
</div>
)
} else {
{console.log("if you see an array under this comment," +
"that means the above if statement read the state's currentWeather array's length" +
" as zero. EVEN THOUGH the componentWillReceiveProps method" +
" updated and set the state accordingly...")}
{console.log(this.state.currentWeather)}
return <p></p>
}
}
улучшенные подробности регистрации
Повторяю, в моем компоненте будет получена функцияprops: "console.log ('nextProps.weatherArray)" ДЕЛАЕТиспустить полный массив данных ... ОДНАКО, "console.log ('this.state.currentWeather)" не делает.Даже после запуска setState.Но затем, когда я использую React Chrome Dev Tools, вы можете видеть, что DID состояния передается в дочерний компонент.Мой метод рендеринга просто не может прочитать данные по какой-то причине ..
THIRD EDIT
Этот первый фрагмент моего родительского компонента.Вы можете видеть, что он передает weatherArray в подпорки ребенка.Кстати, эта функция getWeather работает, я проверял ее с помощью логирования.Проблема в том, что это мой ребенок, я в этом уверен.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {weatherArray: []}
this.getWeather = this.getWeather.bind(this);
}
async getWeather() {
const newWeather = await WeatherHelper.inputPrompt();
console.log(newWeather)
this.setState({weatherArray: newWeather})
WeatherHelper.showData()
}
render() {
return (
<div>
<div id='main'>
<div id='introduction'>
<Intro />
</div>
<div id='attachment'>
<Attachment getWeather={this.getWeather} />
</div>
<div id='body'>
<div id='about'>
<About />
</div>
<div id='personal-info-skills'>
<div id='info'>
<p id='info-header'>personal information</p>
<Info />
</div>
<div id='pskills'>
<p id='pskills-header'>personal skills</p>
<PSkills />
</div>
</div>
<div className='divider'>
<p></p>
</div>
<div id='professions-languages'>
<div id='professions'>
<p id='professions-header'>professions</p>
<Professions />
</div>
<div id='languages'>
<p id='languages-header'>languages</p>
<Languages />
</div>
</div>
</div>
</div>
<div id='side-apps'>
<div id='weather-side-app'>
<WeatherApp weatherArray={this.state.weatherArray} />
</div>
</div>
</div>
)
}
}
Теперь я опубликую фрагмент кода моего ребенка после комментирования componentWillReceiveProps.Вместо того, чтобы пытаться отобразить данные в состоянии моего ребенка, теперь я просто пытаюсь использовать данные реквизита, которые были переданы из родительского компонента ребенка.К сожалению, я все еще сталкиваюсь с той же проблемой.Функция рендеринга моего ребенка читает массив реквизитов как пустой и поэтому не может отображать данные.Я не могу убрать оператор if в начале метода рендеринга, потому что тогда мой код выдает ошибки, когда он пытается прочитать атрибуты пустого массива
render() {
if (this.props.weatherArray.length > 0) {
return (
<div class='weatherApp-main'>
<div className='close-sidebar-button'>
<img src='https://i.postimg.cc/hj0rYKxc/close-button.png' onClick={this.handleCloseClick}/>
</div>
<div id='weather-app-header'>
{this.props.weatherArray.map(item => <div><span>{item.city}</span></div>)}
<h3></h3>
<h4></h4>
</div>
<div id='weather-app-table'>
</div>
</div>
)
} else {
{console.log("if you see an array under this comment," +
"that means the above if statement read the state's currentWeather array's length" +
" as zero. EVEN THOUGH the React Chrome Dev Tools shows that" +
" the child has a full currentWeather array in props...")}
{console.log(this.state.currentWeather)}
return <p></p>
}
}
}
до запуска снимка экрана функции getWeather
после запуска снимка экрана функции getWeather
Посмотрите на два приведенных выше снимка экрана.Первый - до того, как я запустил свою функцию извлечения, поэтому инструменты разработки React Chrome показывают, что массив props моего ребенка пуст (конечно).НО на следующем снимке экрана показано, что, хотя инструменты React Dev показывают, что реквизиты моего дочернего компонента имеют полный массив, мой метод рендеринга по-прежнему считывает длину массива реквизитов как 0 ....