Я как бы потерял доступ к информации в моих статических данных. Вот данные:
{
"info1": {
"label": "label",
"class": "class-css",
"title": "title",
"text": "text",
"number": "20",
"tags": [
{
"name": "#twitter"
},
{
"name": "#myspace"
}
]
},
"info2": {
"label": "label",
"class": "class-css",
"title": "title",
"text": "text",
"number": "20",
"tags": [
{
"name": "#instagram"
},
{
"name": "#facebook"
}
]
}
}
Тогда я получаю такую первую информацию:
this.setState({
currentLabel: this.state.labels["info1"]
})
Вот почему я хочу, а затем я хочу отображать информацию в компоненте, и он работает, пока я не попытаюсь получить информацию tags. Я попробовал .map(), но безуспешно и без ошибок.
<View>
<Text>{infoDetail.title}</Text>
<Text>{infoDetail.text}</Text>
<Text>How do I get "tags" information</Text>
</View>
Можно ли получить доступ к этим объектам в массиве «теги»?
Если я попробую это, и у меня будет "undefined": const tagsItems = this.state.currentLabel.tags.map((tag, index) => { return <Text key = {index}>{tag.name}</Text> }) Если я сделаю так, то все заработает: const tagsItems = this.state.labels["r1"].tags.map((tag, index) => { return <Text key = {index}>{tag.name}</Text> })



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


да, вы можете вызывать теги следующим образом: infoDetail.tags и делать на нем карту
render(){
const tagItems = infoDetail && infoDetail.tags.map((item, index) => {
return <Text key = {index}>{item.name}</Text>
});
return(
<View>
<Text>{infoDetail.title}</Text>
<Text>{infoDetail.text}</Text>
{tagItems}
</View>
)
}
Дело в том, что я использую функциональный (без сохранения состояния) компонент, поэтому я передаю свои реквизиты: <LabelDetail infoDetail = {this.state.currentLabel} />, затем я использую infoDetail для отображения каждой информации .. но map() не работает
Сначала вам нужно проверить, действительно ли infoDetail есть данные или нет, а затем только сопоставить их. Поскольку вы делились только фрагментами кода, я просто посоветовал вам, как вы можете сделать на нем карту и отобразить. Поэтому вам нужно выполнить условную проверку, потому что выполнение map. Я обновил свой ответ, пожалуйста, посмотрите, вы поймете
Наверное, как-то так.
<Text>{infoDetail.tags.map(tag => {/*render */})}</Text>
Вы можете попробовать Object.keys() и Array.prototype.reduce(), чтобы получить свои любимые данные:
const data = {
"info1": {
"label": "label",
"class": "class-css",
"title": "title",
"text": "text",
"number": "20",
"tags": [
{
"name": "#twitter"
},
{
"name": "#myspace"
}
]
},
"info2": {
"label": "label",
"class": "class-css",
"title": "title",
"text": "text",
"number": "20",
"tags": [
{
"name": "#instagram"
},
{
"name": "#facebook"
}
]
}
};
const tags = Object.keys(data).reduce((result, key) => {
return result.concat(data[key].tags);
}, [])
console.info(tags);
/* tags = [
{
"name": "#twitter"
},
{
"name": "#myspace"
},
{
"name": "#instagram"
},
{
"name": "#facebook"
}
] */Вот полный рабочий код. Поскольку ваше свойство состояния labels является объектом, вам нужно как-то сопоставить его. Я выбрал здесь Object.values. Вы можете использовать Object.keys или даже Object.entries в соответствии с вашими потребностями.
Я использовал отдельный компонент Info и передавал ему значения, а затем выполнял рендеринг. В этом компоненте мы снова отображаем tags, а затем визуализируем список.
class App extends React.Component {
state = {
labels: {
info1: {
label: "label1",
class: "class-css",
title: "title",
text: "text",
number: "20",
tags: [
{
name: "#twitter",
},
{
name: "#myspace",
},
],
},
info2: {
label: "label2",
class: "class-css",
title: "title",
text: "text",
number: "20",
tags: [
{
name: "#instagram",
},
{
name: "#facebook",
},
],
},
},
}
render() {
const { labels } = this.state;
return (
<div>
{
Object.values( labels ).map( value =>
<Info label = {value} key = {value.label} /> )
}
</div>
);
}
}
const Info = ( props ) => {
const { title, text, tags } = props.label;
const tagList = tags.map( tag => <p key = {tag.name}>{tag.name}</p> );
return (
<div style = {{ border: "1px solid gray", marginTop: "-1px" }}>
<p>{title}</p>
<p>{text}</p>
<div>{tagList}</div>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id = "root"></div>Обновлять
Если ваши данные полностью статичны, тогда метод @Xavi A. - хороший вариант. Я не знаю, как поживает ваш список, но я предоставляю простой код, включающий что-то вроде того, что вы хотите здесь.
const labels = {
info1: {
label: "label1",
class: "class-css",
title: "title",
text: "text",
number: "20",
tags: [
{
name: "#twitter"
},
{
name: "#myspace"
}
]
},
info2: {
label: "label2",
class: "class-css",
title: "title",
text: "text",
number: "20",
tags: [
{
name: "#instagram"
},
{
name: "#facebook"
}
]
}
};
class App extends React.Component {
state = {
currentLabel: Object.keys(labels)[0]
};
handleInfoChange = info => this.setState({ currentLabel: info });
renderList = () => (
<ul>
{Object.keys(labels).map(info => (
<Item key = {info} info = {info} onClick = {this.handleInfoChange} />
))}
</ul>
);
render() {
const { currentLabel } = this.state;
return (
<div>
{this.renderList()}
<Info currentLabel = {currentLabel} />
</div>
);
}
}
const Item = props => {
const { info, onClick } = props;
const handleClick = () => onClick(info);
return <li onClick = {handleClick}>{info}</li>;
};
const Info = props => {
const { currentLabel } = props;
const { title, text, tags } = labels[currentLabel];
const tagList = tags.map(tag => <p key = {tag.name}>{tag.name}</p>);
return (
<div style = {{ border: "1px solid gray", marginTop: "-1px" }}>
<p>{title}</p>
<p>{text}</p>
<div>{tagList}</div>
</div>
);
};
ReactDOM.render( <App />, document.getElementById( "root" ) );<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id = "root"></div>Он работает, но отображает все данные, а не только первый (текущий / выбранный ярлык), но спасибо, это хороший пример, которому я могу следовать !!
Добро пожаловать. Итак, есть ли список, который вы можете выбрать? Конечно, что-то можно написать по этому случаю.
Дело в том, что у меня есть этот список с «info1, info2, ... и т. д.». Я хочу, чтобы был выбран первый элемент, а затем я буду управлять состоянием с помощью onPress на нескольких элементах, чтобы переключаться между info1 или info4, или info5 ... currentLabel изменится ;-)
Хорошо, ваши данные полностью статичны или вы получаете их асинхронно откуда-то еще?
спасибо @devserkan. Теперь я полностью понял! Все работает нормально. Итак, наконец, я использую this.setState({currentLabel: Object.values(labelsInfo)[0]}), ... и я даже могу .map() мой tags. Так круто. Знаешь, я все еще учусь, и иногда я не понимаю, что делаю, а иногда что-то получалось, и я не помню, как :-)
В данном случае это полностью статические данные. У меня есть другие компоненты с API Call с Axios, но он работает. Спасибо еще раз
Добро пожаловать. Если что-то нечеткое, не стесняйтесь спрашивать здесь. Я могу объяснить немного больше. Если вы новичок, настоятельно рекомендую Официальная документация React. Для других вещей, таких как map, Object.keys, пусть MDN будет вашим другом, близким :)
Нет необходимости сохранять все статические данные в вашем состоянии, вы можете сохранить свое состояние в чистоте, просто сохранив выбранную метку:
onLabelSelect = label => {
//label will be "info1" for example
this.setState({
currentLabel: label
})
}
Затем в вашем рендере:
render(){
//get infoDetail from staticData
const infoDetail = staticData[this.state.currentLabel]
return (
<View>
<Text>{infoDetail.title}</Text>
<Text>{infoDetail.text}</Text>
{infoDetail.tags.map( ({name}) => <Text>name</Text>)}
</View>
)
}
Примечание о карте. Этот:
{infoDetail.tags.map( ({name}) => <Text>name</Text>)}
это более короткая версия:
{infoDetail.tags.map( item => {
return <Text>item.name</Text>
})}
Не могли бы вы поделиться кодом, который вы пробовали с
.map, я попробовал ваш JSON с.map, и он работал нормально.