Я пытаюсь скрыть или показать элемент HTML на основе наличия ключа JSON в данных, которые я ввожу. Если ключ существует, я хотел бы показать идентификатор элемента, в который я помещаю этот объект. Если ключ не существует, я бы хотел скрыть тот же идентификатор элемента. Я использую React и не уверен, принадлежит ли он к componentDidMount или к обычной функции. Я новичок, поэтому приношу свои извинения, если я случайно пропустил важный код или пишу дрянной материал.
Мой код componentDidMount:
componentDidMount = () => {
// Need to hide an the HTML element if the json key doesn't exist in the object
//check the JSON object for the key "workExamples"
if (typeof props.workItemData.workExamples === "undefined") {
console.info("it did not find the json key");
// Change element styling to hidden
document.getElementById("work-examples").style.visibility = "hidden";
} else {
return;
}
};
Мой HTML:
<span id = "work-examples" className = "work-examples">
<a href = {props.workItemData.workExamples}>Work Examples</a>
</span>
Я предполагаю, что мне не нужно публиковать свои объекты JSON. У меня есть несколько; только у одного есть ключ workExamples. Я использую .map() для перечисления объектов.
С помощью приведенного выше кода он не скрывает элементы в списке для объектов JSON, у которых нет ключа. Надеюсь, все это имеет смысл. Любая помощь приветствуется.



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


Если вы просто берете опору и потенциально выводите ее, вы можете сделать ее простой и просто указать то, что вам нужно, в переменной.
render() {
let conditionalElement = null;
if (props.workItemData.workExamples) {
conditionalElement = (
<span id = "work-examples" className = "work-examples">
<a href = {props.workItemData.workExamples}>Work Examples</a>
</span>
);
}
return (
<div>
{conditionalElement}
</div>
);
}
Это позволит вам иметь нулевое значение, которое при необходимости может быть введено в JSX (ничего не даст), затем проверьте, есть ли там свойство, а затем замените нулевое значение своим JSX.
Кроме того, да, используйте стандартный синтаксис функции componentDidMount () {}, и typeof был бы ненужным.
Как отмечает Люк в комментариях,
the logic for whether or not to render should live in
render
Механика этого с тех пор была рассмотрена в других ответах здесь, поэтому я не буду вдаваться в подробности.
Еще несколько моментов:
Вы пытаетесь использовать стрелочную функцию для определения стандартной функции React componentDidMount, и, основываясь на быстром локальном тесте, я не думаю, что React может это понять. Не похоже, что вы получаете от него какую-то особую выгоду по сравнению с традиционным синтаксисом componentDidMount() { /* do stuff here */ }, поэтому я бы переключился на последний.
Вы пытаетесь проверить, содержит ли ваш JSON ключ с
typeof props.workItemData.workExamples === "undefined"
но я не вижу необходимости в typeof; вы можете просто проверить наличие ключа напрямую:
if (props.workItemData.workExamples) { /* do stuff */ }
Наконец, в вашем HTML строка
<a href = {props.workItemData.workExamples}>Work Examples</a>
пытается установить значение href с помощью значения из JavaScript (материал в фигурных скобках). Это справедливо для JSX, что имеет смысл, поскольку вы используете React, но не в чистом HTML. Но поскольку страница загружается и просто не обрабатывает определенную часть логики правильно, я предполагаю, что вы имели в виду только HTML-подобные вещи внутри вашего JSX (файл something.js), а не буквально файл HTML.
Ах, скучал по лесу из-за деревьев на этом. Спасибо за совет (я тоже новичок в React).
if (props.workItemData.workExamples) { /* do stuff */ } оказался тем, что мне было нужно. Я поместил это в componentDidMount, и если он обнаружил, что ключ JSON, он изменил идентификатор элемента со скрытого на видимый. Думаю, я понимаю все комментарии о том, что мне может не понадобиться весь componentDidMount, и я могу просто опустить логику внутри render? Я знаю, что недостаточно разбираюсь во всем этом, чтобы быстро и эффективно описывать вещи - мои извинения. Я учусь .... но я всем вам благодарен.
Я не думаю, что люди говорят, что вам вообще не нужен componentDidMount, это зависит от того, что еще вы там делаете. Официальная ссылка на документы: reactjs.org/docs/react-component.html#componentdidmount Насколько я понял, сообщение заключалось в том, что использование render - это «способ React» (и является является фундаментальной частью React). Даже если нет странных взаимодействий с другим кодом, вы получаете преимущество в удобстве сопровождения, поскольку другие разработчики или даже будущее - вы, вероятно, будете искать рендеринг там, а не ожидать его где-либо еще. Вы знаете, разделение забот, сплоченность и т. д.
Попробуй это
render(){
return props.workItemData.workExamples && (
<span id = "work-examples" className = "work-examples">
<a href = {props.workItemData.workExamples}>Work Examples</a>
</span>)
}
Код, который вы разместили, действительно не имеет никакого смысла. Вы должны прочитать о React и о том, как он работает. Вам никогда не понадобится DOM-select-by-ID для HTML-элемента, отображаемого компонентом React из этого компонента React. Вместо этого вы просто заставляете функцию рендеринга компонента React проверять ваше условие, а затем соответствующим образом отображать HTML.
За исключением того, что на самом деле здесь вы даже не можете этого делать, потому что если вы используете карту так, как я думаю (вы не публиковали свои данные, поэтому трудно сказать), вы можете просто сгенерировать HTML элемент для каждого элемента в массиве. Поэтому, если его нет в массиве, он не будет map ().
render() {
let workItems = this.props.workItemData ? this.props.workItemData.map((item) =>
<span id = {Object.keys(item)[0]} className = {Object.keys(item)[0]}>
<a href = {item[Object.keys(item)[0]]}>{Object.keys(item)[0]}</a>
</span>
) : '';
return (
<div>
{workItems}
</div>
);
Голосование за это. Другие предлагаемые решения работают нормально, но вы фактически указываете причину, по которой метод OP не имеет никакого смысла при использовании React.
Я бы удалил объекты без ключа до того, как был создан какой-либо из их соответствующих компонентов. Что-то вроде:
render() {
return (
<div>
{
Object.keys(workItems)
.filter(item => item.workExamples)
.map(item => <YourComponent {...item} />)
}
</div>
)
}
В React я хотел отображать только существующие элементы после сопоставления, поэтому в элемент списка я добавил логику CSS:
render() {
return (
<div>
{
data.map ((item) => {
return (<div>
<li>{item.answer1}</li>
<li>{item.answer2}</li>
<li>{item.answer3}</li>
<li style = {{display: item.answer4 ? 'block' : 'none'}}>
{item.answer4}</li>
<li style = {{display: item.answer5 ? 'block' : 'none'}}>
{item.answer5}</li>
<li style = {{display: item.answer6 ? 'block' : 'none'}}>
{item.answer6}</li>
) ) } ) }
Хорошие выноски, но здесь важно то, что логика того, следует ли выполнять рендеринг, должна жить в
render.