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" ?
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" ?
Share Improve this question asked Sep 19, 2018 at 15:54 Clément CREUSATClément CREUSAT 3213 gold badges6 silver badges13 bronze badges 2 |5 Answers
Reset to default 4yes 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>
)
}
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>
Probably something like this.
<Text>{infoDetail.tags.map(tag => {/*render */})}</Text>
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"
}
] */
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>
})}
.map
, I tried your JSON with.map
and it worked just fine. – Prasun Commented Sep 19, 2018 at 16:04const tagsItems = this.state.currentLabel.tags.map((tag, index) => { return <Text key={index}>{tag.name}</Text> })
If I do it like this, it's working :const tagsItems = this.state.labels["r1"].tags.map((tag, index) => { return <Text key={index}>{tag.name}</Text> })
– Clément CREUSAT Commented Sep 19, 2018 at 19:32