Я использую React и хочу сделать что-то вроде этого:
Где синие квадраты изначально скрыты и отображаются в зависимости от того, какой Colecao выбрал пользователь. Итак, какой-то Classes с каким-то Colecao внутри, где у каждого из них есть «квадраты». Это мой app.js:
class App extends Component {
constructor(props) {
super(props);
this.state = {
activeTab: 'Classe 1',
tabs: [
{
tituloTab: 'Classe 1',
colecoes: [{
'Colecao 1': [
'A', 'B', 'C', 'D'
],
'Colecao 2': [
'A', 'B', 'C', 'D', 'E'
],
}]
},
{
tituloTab: 'Classe 2',
colecoes: [{
'Colecao 1': [
'A', 'B', 'C', 'D'
],
'Colecao 2': [
'A', 'B', 'C', 'D', 'E'
],
}]
},
{
tituloTab: 'Classe 3',
colecoes: [{
'Colecao 1': [
'A', 'B', 'C', 'D'
],
'Colecao 2': [
'A', 'B', 'C', 'D', 'E'
],
'Colecao 3': [
'A', 'B', 'C'
],
}]
},
{
tituloTab: 'Classe 4',
colecoes: [{
'Colecao 1': [
'A', 'B', 'C', 'D'
],
'Colecao 2': [
'A', 'B', 'C', 'D', 'E'
],
'Colecao 3': [
'A', 'B', 'C'
],
'Colecao 4': [
'A', 'B', 'C', 'D', 'E', 'F'
],
}],
}
],
ThumbnailsColecoes: [
{
tituloThumbnail: 'Costas',
texturas: ['A', 'B', 'C', 'D'],
}
],
colecaoSelecionada:
'',
toggleThumbnailsColecoes:
false,
};
}
changeActiveTab(tab) {
this.setState({activeTab: tab});
}
activeTabContent() {
const activeIndex = this.state.tabs.findIndex((tab) => {
return tab.tituloTab === this.state.activeTab;
}
);
return this.state.tabs[activeIndex].colecoes;
}
adicionarColecaoSelecionada(colecao) {
this.setState({colecoesSelecionadas: colecao}, () => {
this.setState({toggleThumbnailsColecoes: true})
}
)
}
render() {
return (
<div className = {"container is-fluid"}>
<TabsArea
activeTab = {this.state.activeTab}
tabList = {this.state.tabs}
changeActiveTab = {this.changeActiveTab.bind(this)}
colecoes = {this.activeTabContent()}
addColecao = {this.adicionarColecaoSelecionada.bind(this)}
colecoesThumbnails = {this.state.ThumbnailsColecoes}
toggleThumbnails = {this.state.toggleThumbnailsColecoes}/>
</Options>
</section>
</div>
);
}
}
export default App;
Мои tabsArea.js
class TabsArea extends Component {
render() {
return (
<div className = {["section", "tabsArea"].join(' ')}>
<TabsHeader
activeTab = {this.props.activeTab}
tabList = {this.props.tabList}
changeActiveTab = {this.props.changeActiveTab}
/>
<TabContent
key = {this.props.activeTab}
colecoes = {this.props.colecoes}
addColecao = {this.props.addColecao}/>
<hr/>
{//should get the Thumbnails for each "Colecao"
this.props.toggleThumbnails
? <ThumbnailAreas
thumbnailAreas = {this.props.colecoesThumbnails}>
</ThumbnailAreas>
: null
}
</div>
)
}
}
export default TabsArea;
tabContent.js
class TabContent extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<ul className = {"uList"}>
{this.props.colecoes.map((list) => {
return <li className = {"li"}>
<a className = {"has-text-black"}
onClick = {() => this.props.addColecao(list)}>
{list} //should get the list of "Colecao"
</a>
</li>
}
)}
</ul>
</div>
)
}
}
export default TabContent;
Вкладка titulo похожа на мой TabHeader, colecoes - это каждый из элементов списка, а массив букв должен соответствовать каждому квадрату. Проблема в том, что мой элемент tabs является объектом, и я не уверен, как передать его на array. Кроме того, где я должен это сделать, в моем app.js и передать массив как props или передать объект и преобразовать его в array на моем компоненте.
Спасибо



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


Используйте библиотеку Lodash:
var arr = _.values(obj);
Если вам это нужно для других целей в app.js, сделайте это там, иначе это не имеет значения.
Извините, моя ошибка. Я думал, что нужно преобразовать объект в массив. Теперь я вижу, что у вас есть один элемент в объекте, который является массивом, и каждый элемент этого массива представляет собой массив с одним элементом, который является объектом ... Сложно ... Я бы попытался определить более простое состояние, но нет пора разобраться в этом сейчас, извините ...
Без проблем. Я не знаю, лучший ли это способ установить состояние, позже он будет получать данные из API и будет похож на параметры «3» слоев: выберите вкладку, на каждой вкладке будет список, и каждый элемент в списке будет есть соответствующие эскизы. Спасибо, любая помощь будет оценена
Если вы будете использовать значение массива в нескольких местах, тогда имеет смысл выполнить преобразование в app.js и передать массив туда, где он должен быть.
Если вы будете использовать значение массива только в одном компоненте, просто передайте в него объект и позвольте ему делать все, что ему нужно, о чем app.js не должен заботиться.
Что касается преобразования объекта в массив, есть много способов сделать это, и это зависит от вашего конкретного варианта использования. Глядя на ваш пример, похоже, что tabs уже является массивом ... Мне что-то здесь не хватает?
Да, это массив, но он передается как объект с ключами, верно? Возможно, я что-то упускаю, впервые работаю с этим ...
Просто передайте массив в любую функцию, которую вы хотите в своем компоненте, и прокрутите его там ... это должно сработать, я не понимаю, почему это не так. Все в JavaScript - это «объект» под капотом, так что в этом смысле да, ваш массив является объектом, но он по-прежнему является циклическим массивом.
Пытался, но получаю: «Объекты недействительны как дочерние элементы React (найдено: объект с ключами {Colecao 1, Colecao 2}). Если вы хотели визуализировать коллекцию дочерних элементов, используйте вместо этого массив».
Не могли бы вы показать мне, как вы используете свой код? Отредактируйте свой вопрос с помощью обновленного кода. Может ты плохо им пользуешься. Попробуйте сделать что-нибудь вроде <MyChildComponent tabs = {this.state.tabs} /> или что-нибудь в этом роде. Поскольку tabs - это массив, это должно работать ...
В вашем TabContent вы выполняете this.props.colecoes.map(list => ...) ... аргумент не будет списком, это будет объект. Каждая итерация функции map передает единственный аргумент, а не сам список ... Попробуйте изменить это и содержимое метода addColecao, чтобы ожидать объект, а не список.
Мне жаль, но я что-то упускаю. Когда я console.info мои вкладки и "let array = _.values (this.state.tabs);" Получаю тот же результат ...