Я пытаюсь изменить состояние компонента, который является частью сопоставленного массива объектов из файла json. Я хочу ТОЛЬКО изменить элемент, содержащий нажатую кнопку, и ничего другого.
Я пытался установить свойство (projectID) с помощью onClick, и хотя я могу заставить его переключать один элемент состояния (расширенный или нерасширенный), он делает это для ВСЕХ возвращаемых результатов. Поэтому я пытался получить идентификатор проекта (установленный в данных) и использовать его для установки условного выражения. Но я не могу заставить projectId обновляться одним щелчком мыши. Я кратко поиграл с контекстом, но я думаю, что мне не хватает чего-то более простого. Я пытался это сделать в onClick (как показано) и изнутри onViewChange, но это не сработало, так как я не могу получить доступ к item.id из-за пределов сопоставленного элемента.
Я использую условное выражение, основанное на реквизите, переданном от пары уровней выше, чтобы установить категорию, показывающую только те объекты, которые я хочу. Эта часть, кажется, работает. Поэтому я удалил свое расширенное состояние, так как здесь нет необходимости.
import React from 'react';
import projects from '../data/projects.json';
class ProjectCard extends React.Component {
constructor(props) {
super(props);
this.state = {
projects,
expanded: false,
projectId: -1
}
}
onViewChange = (e) => {
this.setState({
expanded: !this.state.expanded
});
console.info(this.state.projectId)
};
render() {
return (
<React.Fragment>
{this.state.projects.map((item) => {
if (!this.state.expanded && item.category === this.props.category) {
return (
<div key = {item.id} className = "project-card">
<div className = "previewImg" style = {{backgroundImage: `url(${item.previewImg}` }} ></div>
<div className = "copy">
<h2>{item.title}</h2>
<p>{item.quickDesc}</p>
</div>
<div className = "footer">
{item.tools.map((tool) => {
return (
<div key = {tool} className = "tools" style = {{backgroundImage: `url(${tool}` }}></div>
);
}
)}
<button onClick = {() => this.onViewChange({projectId: item.id})} className = "btn float-right"><i className = "fas fa-play"></i></button>
</div>
</div>
);
}
}
)}
</React.Fragment>
);
};
};
export default ProjectCard;
Я установил консольный журнал, чтобы сообщать мне, изменяется ли projectId, и он всегда возвращается как мое значение по умолчанию (-1). Вставленная версия - единственная, которая не выдает ошибок в отношении неопределенных значений/объектов, но по-прежнему никаких изменений. Если я смогу заставить проект измениться на основе item.id с помощью нажатой кнопки, я думаю, что смогу понять условное выражение и взять его оттуда.
На самом деле вы не устанавливаете состояние с новым projectId
в обработчике кликов. Первый шаг — просто передать идентификатор элемента обработчику кликов, а не объекту:
onClick = {() => this.onViewChange(item.id)}
И вторая часть заключается в том, чтобы фактически использовать этот аргумент в вашем обработчике кликов:
onViewChange = (id) => {
this.setState({
expanded: !this.state.expanded,
projectId: id
});
};
Кроме того, setState()
является асинхронным, поэтому вы не можете делать то, что делали, и console.info
свое состояние на следующей строке и ожидать, что оно изменилось. Зарегистрируйте состояние в верхней части вашей функции рендеринга, чтобы увидеть, когда оно изменится (после изменения состояния/реквизитов вызывается рендеринг). Или другой вариант — использовать необязательный второй аргумент setState
, который представляет собой обратный вызов, выполняемый с новым состоянием:
this.setState({id: 5}, () => console.info(this.state.id)) <-- id will be 5
@cebronix не беспокойтесь :) кстати, если вы тоже хотите пройти мероприятие, вы можете поставить лайк: onClick = {(event) => someFunction(event, ...otherArgs)}
Это сработало отлично, спасибо! Я помню, как пробовал this.onViewChange(item.id) - и десятки других догадок "что, если я сделаю это", но я думаю, что упустил ту часть, где id передается обратно в onViewChange вместо передачи события. 60 часов обучающих видео, и это первый неучебник, который я пытаюсь пройти. Я очень ценю помощь!