У меня возникает ошибка, когда я использую propTypes и дочерние элементы условного рендеринга.
Ошибка: Warning: Failed prop type: The prop 'rate' is marked as required in 'Rate', but its value is 'undefined'
// index.js
import React, { Component } from "react";
import { render } from "react-dom";
import Rate from "./components/Rate";
import Card from "./components/Card";
class App extends Component {
state = {
loading: true
};
componentDidMount() {
setTimeout(() => this.setState({ loading: false, rate: 5 }), 5000);
}
render() {
return (
<Card loading = {this.state.loading}>
<Rate rate = {this.state.rate} />
</Card>
);
}
}
render(<App />, document.getElementById("root"));
// rate.js
import React from "react";
import PropTypes from "prop-types";
const Rate = ({ rate }) => (
<div>
<span>{rate}/10</span>
</div>
);
Rate.propTypes = {
rate: PropTypes.number.isRequired
};
export default Rate;
Я воспроизвел здесь свою ошибку: https://codesandbox.io/embed/qvx8q78ypw
Я хочу отображать дочерний элемент, только если для загрузки установлено значение false.
Обновлено: я не понимаю, почему я получаю эту ошибку в компоненте Rate, пока она не будет отображена
Я не понимаю, почему я получаю эту ошибку.
Спасибо за помощь



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы пытаетесь загрузить компонент <Rate /> с опорой rate, равной this.state.rate в <App />. В состоянии вашего компонента приложения ничего не установлено для this.state.rate, поэтому, хотя <Rate /> ожидает PropTypes.Number, на самом деле он получает undefined. Вот почему он жалуется.
Чтобы решить эту проблему, вы можете установить состояние для <App /> примерно так:
state = {
loading: true
rate: 0,
};
@mdck, если это undefined, а ваш компонент ожидает rate: PropTypes.number.isRequired, вам будет плохо.
Да, но я использую условное выражение для рендеринга потомков или нет, почему PropTypes выполняются, если для загрузки установлено значение true?
На данный момент вы можете использовать значение свойства по умолчанию:
Rate.defaultProps = {
rate: 0
};
Вы не делаете Карту условно, как сказал @Cody Moniz в ответе. Вы всегда это делаете. Вероятно, что в компоненте Card вы что-то скрываете или показываете, это зависит от свойства загрузки, которое вы ему передали. Не беспокойтесь об этом, просто используйте условный рендеринг должным образом и, возможно, немного очистите свой компонент Card.
render() {
return !this.state.loading && (
<Card>
<Rate rate = {this.state.rate} />
</Card>
);
}
Здесь, если React получает значение null или false, он ничего не отображает. Итак, когда ваше состояние загрузки - false, вы ничего не визуализируете, после того, как оно изменится на true, вторая часть оценивает и отображает ваш компонент. Вторая часть не оценивается до тех пор, пока первая не станет истинной с помощью логического оператора &&. Это хороший и чистый способ сделать условный рендеринг, особенно если вы не хотите ничего показывать в первом условии.
Если вы хотите показать что-то о Card (то есть визуализировать его), но только условно визуализировать компонент Rate, вы можете применить эту логику в своем компоненте Card с загрузочной опорой, которую получает ваш компонент Card.
Это может работать, но я не понимаю, почему я получаю эту ошибку в компоненте Rate, пока она не будет отображена.
Хорошо, я отредактировал свой ответ и немного расширил его, что сказал @Cody Moniz.
<Rate> все еще обрабатывается в <App>, единственное, что делает <Card>, - это скрывает или показывает уже отрендеренные элементы this.props.children, переданные ему.
Спасибо за ответ, но в моем реальном приложении я использую redux, а значение
rateравноundefined, а через несколько секунд я получаю значение. Так что я могу установитьrate: 0в моем состоянии