Reputation: 321
I'm kind of lost to access some info in my static data. Here's the 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"
}
]
}
}
Then I get the first info like that :
this.setState({
currentLabel: this.state.labels["info1"]
})
This is why I want and then I want to display info in a component and it's working until I try to get tags
information. I tried a .map()
but without success and error.
<View>
<Text>{infoDetail.title}</Text>
<Text>{infoDetail.text}</Text>
<Text>How do I get "tags" information</Text>
</View>
Is it possible to access these objects in the array "tags" ?
Upvotes: 2
Views: 24133
Reputation: 33994
yes you can call tags as follows infoDetail.tags and do map on it
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>
)
}
Upvotes: 4
Reputation: 17608
Here is a full working code. Since your labels
state property is an object, you need to map it somehow. I've chosen Object.values
here. You can use Object.keys
or even Object.entries
according to your needs.
I've used a separate Info
component and passed the values to it, then render there. In this component, we are again mapping the tags
, then rendering the list.
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>
Update
If your data is totally static then @Xavi A.'s method is a good option. I don't know how is your list but I provide a simple code including something like you want here.
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>
Upvotes: 3
Reputation: 825
No need to save all the static data in your state, you can keep your state cleaner by just saving the selected label:
onLabelSelect = label => {
//label will be "info1" for example
this.setState({
currentLabel: label
})
}
Then in your render:
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>
)
}
Note about the map. This:
{infoDetail.tags.map( ({name}) => <Text>name</Text>)}
is a shorter version of:
{infoDetail.tags.map( item => {
return <Text>item.name</Text>
})}
Upvotes: 2
Reputation: 6629
You can try Object.keys()
and Array.prototype.reduce()
to get your favorite data:
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.log(tags);
/* tags = [
{
"name": "#twitter"
},
{
"name": "#myspace"
},
{
"name": "#instagram"
},
{
"name": "#facebook"
}
] */
Upvotes: 2
Reputation: 63
Probably something like this.
<Text>{infoDetail.tags.map(tag => {/*render */})}</Text>
Upvotes: 3