I have an object named data that contains information about book. The simplest thing I want to do is render the book name. I am trying like below. Not working.
const data = {
"book": {
"id": "2d320",
"name": "book 1",
"Chapters": [
{
"No": "1",
"date": "2010-04-22",
"plots": [
{
"name": "Hero"
}
]
},
{
"No": "2",
"date": "2010-04-22",
"plots": [
{
"name": "Heroine"
}
]
},
]}}
export class Books {
render() {
return (
<View>
<div>{data.book.name}</div>
</View>
);
}
}
div should not be used in react-native, just replace it with Text after importing it. Secondly, class-based components should extend React.Component like so
import React, { Component } from 'react';
import { Text, View } from 'react-native';
const data = {
book: {
id: '2d320',
name: 'book 1',
Chapters: [
{
No: '1',
date: '2010-04-22',
plots: [
{
name: 'Hero',
},
],
},
{
No: '2',
date: '2010-04-22',
plots: [
{
name: 'Heroine',
},
],
},
],
},
};
class Book extends Component {
render() {
return <View>
<Text>{data.book.name}</Text>
</View>;
}
}
export default Book;
Here is a snack displaying the output you want.
If you don't want to import Component from 'react' and like to export directly then may also use this syntax
export default class Book extends React.Component {
render() {
return (
<View>
<Text>{data.book.name}</Text>
</View>
);
}
}
Related
I want to call the function using the key name from the array on the tab.screen component.
my code is like this:
import React from 'react';
import { Text, View, TouchableOpacity, Modal } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import Icon from 'react-native-vector-icons/FontAwesome5';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Home from '../mainscreen/GeneralScreen';
import Core from '../mainscreen/CoreScreen';
import Docs from '../mainscreen/GeneralScreen';
import ESS from '../mainscreen/GeneralScreen';
import General from '../mainscreen/GeneralScreen';
import HR from '../mainscreen/GeneralScreen';
import Payroll from '../mainscreen/GeneralScreen';
import Server from '../mainscreen/CoreScreen';
const Tab = createBottomTabNavigator();
const tabcomponents = {
"Home" : Home,
"Core" : Core,
"Docs" : Docs,
"ESS" : ESS,
"General" : General,
"HR" : HR,
"Payroll" : Payroll,
"Server" : Server
};
class TabNavigator extends React.Component {
constructor() {
super();
this.state = {
dashboardtab:[],
}
this.tabnavigatorasync();
}
tabnavigatorasync = async () => {
try {
const dashboardtab = await AsyncStorage.getItem('dashboardtab');
const dashboardtabParse = JSON.parse(dashboardtab);
this.setState({dashboardtab: dashboardtabParse});
//console.log('isi dari tab navigator: ', this.state.dashboardtab);
//console.log('------------------------------------------------');
//console.log('isi dari tab navigator 2: ', this.state.dashboardtab2[0].label);
} catch (error) {
}
}
render(){
//console.log('dashboardtab', this.state.dashboardtab);
const tabnavigatorRender = this.state.dashboardtab.map((item, index) =>
const tabcomponentsrender = tabcomponents[item.admintab.label];
return <Tab.Screen name={item.admintab.label} component={tabcomponentsrender} key={index}/>
);
return(
<Tab.Navigator>
{tabnavigatorRender}
</Tab.Navigator>
)
}
}
export default TabNavigator;
the result appears an error like this:
Invariant Violation: View config getter callback for component Home must be a function (received undefined)
This is the contents of the array:
[
{
"tab_id": "home",
"order": 10,
"admintab": {
"label": "Home",
}
},
{
"tab_id": "core",
"order": 1,
"admintab": {
"label": "Core",
}
},
{
"tab_id": "docs",
"order": 2,
"admintab": {
"label": "Docs",
}
},
{
"tab_id": "ess",
"order": 50,
"admintab": {
"label": "ESS",
}
},
{
"tab_id": "general",
"order": 45,
"admintab": {
"label": "General",
}
},
{
"tab_id": "hr",
"order": 40,
"admintab": {
"label": "HR",
}
},
{
"tab_id": "payroll",
"order": 42,
"admintab": {
"label": "Payroll",
}
},
{
"tab_id": "server",
"order": 70,
"admintab": {
"label": "Server",
}
}
]
is there something wrong with the code i made?
In your case, you want to use Dynamic Component Names.
First of all import your tabs.
import Home from 'path_to_your_tab_component/Home';
import Core from 'path_to_your_tab_component/Core'; // and so on
Then pass them in the object and give them a key based on their names.
const components = {
"Home": Home
"Core": Core // and so on
}
Inside the map, create a component from this object.
const tabnavigator = this.state.dashboardtab.map((item, index) => {
const TabComponent = components[item.admintab.label];
return <Tab.Screen name={item.admintab.label} component={TabComponent} key={index}/>
});
I've been stuck for whole day and please help me to fix it.
I have a json data which like this :
[
{
"menu": "menu_1",
"icon": "icon_1",
"detail": {
"name": "name_1",
"phone": "phone_1"
}
},
{
"menu": "menu_2",
"icon": "icon_2",
"detail": {
"name": "name_2",
"phone": "phone_2"
}
},
{
"menu": "menu_3",
"icon": "icon_3",
"detail": {
"name": "name_3",
"phone": "phone_3"
}
}
]
I put them into the "data" state and My goal is I wanna change the "detail" state with certain index ( ex: state "data" with index 1 change the "detail" data )
Currently my code is :
this.setState({
data: {
...this.state.data,
detail:{
this.state.data[1].detail:{
"name": "billy",
"phone": "893823839"
}
}
}
})
That setState is clearly wanna change the state with certain index but fail..
How do I supposed to do?
I guess this is what you're looking for, we could replace an element inside an array using splice :
const index = 1;
this.setState({
data: [...this.state.data].splice(index, 1, {
...this.state.data[index],
details: { name: "billy", phone: "893823839" },
}),
});
Update: we could use slice also to make an immutable update with index :
this.setState({
data: [
...this.state.data.slice(0, index),
{
...this.state.data[index],
details: { name: "billy", phone: "893823839" },
},
...this.state.data.slice(index + 1, this.state.data.length),
],
});
could you try it ?
this is an example that i tested using splice:
const items = [{ id: 1 }, { id: 2 }, { id: 3 }];
const indexToBeModified = 1; // { id: 2 } ==> { foo: "foo", id: 2 }
items.splice(indexToBeModified, 1, { ...items[indexToBeModified], foo: "foo" });
console.log("items", items);
Here is a little modified example. It uses prevState to prevent any unwanted changes that may happen when directly interacting with this.state.
import React, { Component } from "react";
export default class App extends Component {
constructor() {
super();
this.state = {
data: [
{
menu: "menu_1",
icon: "icon_1",
detail: {
name: "name_1",
phone: "phone_1"
}
},
{
menu: "menu_2",
icon: "icon_2",
detail: {
name: "name_2",
phone: "phone_2"
}
},
{
menu: "menu_3",
icon: "icon_3",
detail: {
name: "name_3",
phone: "phone_3"
}
}
]
};
this.modifyData = this.modifyData.bind(this);
}
modifyData(index) {
this.setState((prevState) => {
prevState.data[index].detail={
name: "billy",
phone: "893823839"
};
return {
data: [prevState.data]
};
},()=>{console.log(this.state.data)});
}
render() {
return (
<button onClick={() => this.modifyData(0)}>Click to modify data</button>
);
}
}
Here is a code sandbox reference.
I added my coding's for how to create state like at the end of this question above coding's are i will try but am not able to create like that state.
This is my json format coding to get through
"Results": {
"Piechart":[{
"labels": ["Under 18", "Age 18-54", "Age 55+"],
"datasets": [{
"data": [2000, 4000, 2850],
"backgroundColor": ["red", "blue", "green"]
}]
}]
}
Here is my React Code
this.state = {labels: [], datasets: []};
componentDidMount() {
this.pieChart().then(result => {
this.setState({diagramData: result.pieDiagramLabel});
}).catch(err => console.error(err));
}
async pieChart() {
let pieChart = await import('../data/result_log.json');
console.log(pieChart[0].Results.Piechart);
return {
pieDiagramLabel: pieChart[0].Results.Piechart.labels
}
}
How to get both label and datasets? And how to set into state like below format
this.state= {
"labels": ["Under 18", "Age 18-54", "Age 55+"],
"datasets": [{
"data": [2000, 4000, 2850],
}]
}
You can try like this
data.json
{
"Piechart": [
{
"labels": ["Under 18", "Age 18-54", "Age 55+"],
"datasets": [
{
"data": [2000, 4000, 2850],
"backgroundColor": ["red", "blue", "green"]
}
]
}
]
}
App.js
import React from "react";
import Results from "./data.json";
export default class App extends React.Component {
state = {
labels: [],
datasets: []
};
componentDidMount() {
this.setState({
labels: Results.Piechart[0].labels,
datasets: Results.Piechart[0].datasets
});
}
render() {
const { labels, datasets } = this.state;
return (
<div className="App">
{labels.map((label, index) => (
<p key={index}>{label}</p>
))}
<hr />
{datasets.map((data, index) => (
<p key={index}>{data.backgroundColor}</p>
))}
</div>
);
}
}
Live working demo https://codesandbox.io/s/fetch-local-json-6bq4m
I am performing an Axios get call in a React Component to retrieve JSON info. That function is working great. Within the JSON is a label for various network ports, which are returning as an array in my axios call. These are ultimately going to be displayed as nodes on a d3 graph. My issue is that I need to output the data pulled from the get call into the following format:
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
So the full component for the graph to read is:
export const data = {
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
}
Here is the format of the Axios get I am using:
axios.get(`NetworkConstruct.json`)
.then(res => {
const names = res.data.items;
this.setState({ names });
});
Here is a sample output I am receiving (there are 11 of these):
{id: "5bc0860c-ece1-461c-bac0-b155a3cacd82", label: "80.107.0.212",
resourceTypeId: "tosca.resourceTypes.NetworkConstruct", productId:
"5bc0835c-6cfa-486e-8429-a59eaf4118bc", tenantId: "393fa8da-61fd-458c-80f9-
ce92d0ef0330", …}
The data has to be in this EXACT format or the graph won't read it. I'm guessing I'll need to do an initial map function but am stuck on how to arrange it. I cannot have any divs or quotes in my output. Is this doable? I have scoured the boards and Google for a couple of days and can't make this work yet.
Here is the object I am receiving from the GET request.
{
"id": "5bd2c6ef-6009-4b90-9156-62168f3c6293",
"resourceId": "5bd0ba82-2994-455d-8716-2adb5694d6f0",
"interface": "getGraph",
"inputs": {},
"outputs": {
"graph": {
"nodes": [
{
"id": "5bcdf06c-dd53-4335-840f-55a4b8d85a2d",
"name": "asw-lab9306b",
"ports": {
"GigabitEthernet3/0/8": "5bd1777f-0ab9-4552-962b-9e306ce378ab",
"GigabitEthernet2/0/15": "5bd1777e-119c-44e8-ba69-0d86a481c0f5",
"GigabitEthernet3/0/47": "5bd17783-be94-4aaf-8858-70e4eb3d02dc",
"GigabitEthernet2/0/13": "5bd17783-ed99-453f-a958-f764edaa8da8"
}
}
],
"links": [
{
"a": "5bd1a467-13f2-4294-a768-561187b278a8",
"z": "5bd17770-2e6c-4c37-93c8-44e3eb3db6dd",
"layer": "ETHERNET"
},
{
"a": "5bd1776e-c110-4086-87d6-a374ccee419a",
"z": "5bd17770-83ee-4e10-b5bb-19814f9f5dad",
"layer": "ETHERNET"
}
]
}
},
"state": "successful",
"reason": "",
"progress": [],
"providerData": {},
"createdAt": "2018-10-26T07:49:03.484Z",
"updatedAt": "2018-10-26T07:49:25.425Z",
"resourceStateConstraints": {},
"executionGroup": "lifecycle"
}
The info I need is the nodes ID. There are eleven of them in the full object.
You can map an array of objects to another array of objects in your format with Array.prototype.map(). Assuming that data is the list of objects from your response:
class Graph extends React.Component {
state = {
nodes: null,
};
componentDidMount() {
axios.get('the url').then(response => {
const nodes = response.data.outputs.graph.nodes;
this.setState({nodes});
});
}
render() {
const {nodes} = this.state;
if (!nodes) return 'Loading...'
return <TheD3ComponentYouUse nodes={nodes} />;
}
}
I am trying to show menu where it can have parent child relationship, with flat structure it is working fine but with nested objects not able to do it.
The below is the JSON and reactJS code.
JSON -
{
"data": [
{
"to": "#a-link",
"icon": "spinner",
"label": "User Maintenance"
},
{
"content": [
{
"to": "#b1-link",
"icon": "apple",
"label": "System Controls"
},
{
"to": "#b2-link",
"icon": "user",
"label": "User Maintenance"
}
],
"icon": "gear",
"label": "System Preferences"
},
{
"to": "#c-link",
"icon": "gear",
"label": "Configuration"
}
]
}
ReactJS code -
export default class MenuComponent extends Component {
constructor() {
super();
this.state = {}
}
componentDidMount(){
fetch('http://localhost:8084/Accounting/rest/v1/company/menu?request=abc')
.then(response => response.json())
.then(parsedJSON => parsedJSON.data.map(menu => (
{
to: `${menu.to}`,
icon: `${menu.icon}`,
label: `${menu.label}`
// content: `${menu.content}`
}
)))
.then(content => this.setState({
content
}))
}
render() {
console.log('333');
console.log(this.state.content);
return (
<MetisMenu content={this.state.content} activeLinkFromLocation />
)
}
}
In JSON you can see the 'System Preference' has nested content.
Try this code
class MenuComponent extends Component {
constructor() {
super();
this.state = {
content : []
}
}
componentDidMount(){
fetch('http://localhost:8084/Accounting/rest/v1/company/menu?request=abc')
.then(response => response.json())
.then(parsedJSON => parsedJSON.data.map(menu => (
{
to: `${menu.to}`,
icon: `${menu.icon}`,
label: `${menu.label}`
// content: `${menu.content}`
}
)))
.then(content => this.setState({
content
}))
}
render() {
const {content} = this.state
if(content === undefined){
return <div>Content not found</div>;
}
if(content.length === 0){
return <div>Loading</div>;
}
return (
<MetisMenu content={content} activeLinkFromLocation />
)
}
}
export default MenuComponent