React Native - How to send objects in renderItem? - javascript

I'm receiving data from api like this:
{
"isTrue": true,
"data1": {
"username": "user1",
"images": [
"image1.jpg",
"image2.jpg"
]
},
"data2": {
"location": "new york",
"age": "80"
}
}
and setting it in my state as details.
I want to display data in flatlist, so I do this:
<FlatList
data={state.details}
renderItem={({item}) => {
<Details item={item} />;
}}
></FlatList>
in my component I render data like:
export default Details = ({item}) => {
return item
? Object.values(item).map(value => {
<Text>{value.data1?.username}</Text>;
})
: null;
};
Why don't the items render?

Make sure u pass Array to flat list
like :
const DATA = [
{
id: "bd7acbea-c1b1-46c2-aed5-3ad53abb28ba",
title: "First Item",
},
{
id: "3ac68afc-c605-48d3-a4f8-fbd91aa97f63",
title: "Second Item",
},
{
id: "58694a0f-3da1-471f-bd96-145571e29d72",
title: "Third Item",
},
];
flat list will do for loop for you, so u don't need to values(item).map you can do:
export default Details = ({item}) => {
return
<View>
<Text>{item.isTrue}</Text>
<Text>{item.data1.username}</Text>
</View>
};
change
renderItem={({item}) => {
<Details item={item} />;
}}
to
renderItem={({item}) => {
return <Details item={item} />;
}}
or
renderItem={({item}) => (<Details item={item} />)}
finally don't forget to add <View></View> as parent for <Text><Text>

Related

How can I create a menu with my json info with REACT

what I try to do is to have the same display as this picture :
So in my menu the plant type (Type of plant1) is displayed above a gray bar and when you click on the down chevron then you can see all the plants name, related to this type, with checkboxes on left, by default there will be all checked. And the blue rectangle indicates the number of plants that have been selected.
How can I do that, which package can help me in REACT?
Here my plants.json :
{
"plants_type": [
{
"_id_type": "1",
"name_type": "Type of plant1",
"plants": [
{
"name": "Plant1.1",
"_id": "2"
},
{
"name": "Plant1.2",
"_id": "3"
}
]
},
{
"_id_type": "4",
"name_type": "Type of plant2",
"plants": [
{
"name": "Plant2.1",
"_id": "5"
},
{
"name": "Plant2.2",
"_id": "6"
}
]
}
]
}
You can create a dropdown list on your own like below. I have added the logic of selecting items to the data itself.
You can keep a component called Category to keep a single state of the parent menu item. Whether it's open or not. Then iterate over the plants as checkbox inputs to make them selectable.
I have used a simple initialize function to make all the items selected initially. This should work as you expect. Add a console log of selectionMenu to see how selected property changes while toggling items.
Move the inline styles to CSS classes to make the code more clear.
const data = { plants_type: [ { _id_type: "1", name_type: "Type of plant1", plants: [ { name: "Plant1.1", _id: "2" }, { name: "Plant1.2", _id: "3" } ] }, { _id_type: "4", name_type: "Type of plant2", plants: [ { name: "Plant2.1", _id: "5" }, { name: "Plant2.2", _id: "6" } ] } ] };
const Category = ({ _id_type, name_type, plants, changeSelection }) => {
const [toggleState, setToggleState] = React.useState(false);
return (
<div key={_id_type}>
<div
style={{
cursor: "pointer",
userSelect: "none",
display: "flex",
margin: "2px",
backgroundColor: "lightgray"
}}
onClick={() => setToggleState((prev) => !prev)}
>
<div>{name_type}</div>
<div
style={{
backgroundColor: "blue",
color: "white",
padding: "0px 10px",
marginLeft: "auto"
}}
>
{plants.filter(({ selected }) => selected).length}
</div>
</div>
<div style={{ marginLeft: "10px" }}>
{toggleState &&
plants.map(({ name, _id, selected }) => (
<div key={_id}>
<input
key={_id}
type="checkbox"
value={name}
checked={selected}
onChange={(e) => changeSelection(_id_type, _id, e.target.value)}
/>
{name}
</div>
))}
</div>
</div>
);
};
const App = () => {
const initializeSelectionMenu = (data) => {
return data.map((item) => {
return {
...item,
plants: item.plants.map((plant) => ({ ...plant, selected: true }))
};
});
};
const [selectionMenu, setSelectionMenu] = React.useState(
initializeSelectionMenu(data.plants_type)
);
console.log(selectionMenu);
const changeSelection = (catId, itemId, value) => {
setSelectionMenu((prevSelectionMenu) =>
prevSelectionMenu.map((item) => {
if (item._id_type === catId) {
return {
...item,
plants: item.plants.map((plant) => {
if (plant._id === itemId) {
return { ...plant, selected: !plant.selected };
}
return plant;
})
};
}
return item;
})
);
};
return (
<div>
{selectionMenu.map((item) => (
<Category
{...item}
changeSelection={changeSelection}
key={item._id_type}
/>
))}
</div>
);
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>

REACT- Multiple Tabs don't work, headers and body don't diplayed

I tried to use multiple tabs in react. But it doesn't seem working (please see the picture). I 'm not able to display the header for my Tabs neither the body (from match.json) that should contained a textbox field as input...
import React from "react";
import { Tab, Tabs as TabsComponent, TabList, TabPanel } from "react-tabs";
import "react-tabs/style/react-tabs.css";
const Tabs = ({ data }) => (
<TabsComponent>
<TabList>
{data.map(({ name }, i) => (
<Tab key={i}>{name}</Tab>
))}
</TabList>
{data.map(({ name }, i) => (
<TabPanel key={i}>{name}</TabPanel>
))}
</TabsComponent>
);
export default Tabs;
MenuItemDisplay:
export default function MenuItemDisplay() {
const { match } = JsonData;
...
<Tabs data={match.questions[0]} />
</div>
</>
);
}
match.json :
{
"match": [
{
...
"_ids": [
"questions": [
{
"name": "Tell me about yourself ",
"typeProof": ""
},
...
],
]
}
]
}
The data that you want to send to the Tabs component is the currently matched item's questions array.
const { menuId, itemId } = useParams();
const { match } = JsonData;
const matchData = match.find((el) => el._id_menu === menuId)?._ids ?? [];
const item = matchData.find((el) => el._id === itemId);
Here item is the current menu item being rendered, "Pea Soup", or item "123ml66" for example:
{
"_id": "123ml66",
"name": "Pea Soup",
"description": "Creamy pea soup topped with melted cheese and sourdough croutons.",
"dishes": [
{
"meat": "N/A",
"vegetables": "pea"
}
],
"questions": [
{
"name": "Tell me about yourself ",
"typeProof": ""
},
{
"name": "Why our restaurant?",
"typeProof": ""
},
{
"name": "What hours are you available to work ?",
"typeProof": "Planning"
}
],
"invited": [
{
"name": "Jose Luis",
"location": "LA"
},
{
"name": "Smith",
"location": "New York"
}
],
"taste": "Good",
"comments": "3/4",
"price": "Low",
"availability": 0,
"trust": 1
},
Pass item.questions to the Tabs component.
<Tabs data={item.questions} />
...
const Tabs = ({ data }) => (
<TabsComponent>
<TabList>
{data.map(({ name }, i) => (
<Tab key={name}>Question {i + 1}</Tab>
))}
</TabList>
{data.map(({ name }) => (
<TabPanel key={name}>{name}</TabPanel>
))}
</TabsComponent>
);

Iterate over JS object of arrays

I have this object that I'm trying to loop over in a form but really can't get it to work. Here is sample of the object.
const data = {
"Social Security": [
{
label: "Deduction Type",
value: "Social Security",
name: "SocialSecurity"
},
{
label: "Employer Rate",
value: "12.4%",
name: "SocialEmployer"
},
{
label: "Employee Rate",
value: "6.2%",
name: "SocialEmployee"
}
],
"Medicare": [
{
label: "Deduction Type",
value: "Medicare",
name: "Medicare"
},
{
label: "Employer Rate",
value: "1.45%",
name: "MedicareEmployer"
},
{
label: "Employee Rate",
value: "2.9%",
name: "MedicareEmployee"
}
]
}
form implementation
<Formik>
{({ values, isSubmitting, resetForm, setFieldValue }) => (
<Form id="payrollSettingsForm" >
<Grid container className={classes.border}>
<Grid item xs={12} md={4}>
{Object.entries(data).map(arr =>{
Array.isArray(arr) && arr.map(elm =>{
return (<TextField
label={elm.label}
value={elm.value}
name={elm.name}
/>)
})
})}
</Grid>
</Grid>
...rest of the form
</Form>
</Formik>
Tried many approaches like Object.fromEntries(). forEach I think all the methods I can find example and keep failing, maybe I'm doing something wrong, any help will be appreciated.
{Object.entries(data).map(([key, val]) =>{
return val.map(elm =>{
return (
<TextField
label={elm.label}
value={elm.value}
name={elm.name}
/>
)
})
})}
Map should return an element on each iteration. In case you don't want to display return null else return a react node.
<Grid item xs={12} md={4}>
{Object.entries(data).map(arr => {
Array.isArray(arr) ? arr.map(elm => {
return (<TextField
label={elm.label}
value={elm.value}
name={elm.name}
/>)
}) : null
})}
</Grid>

How to setState on Object item within array

I want to update state of key heart in the array's objects when the heart icon pressed it changes to red so for this I'm using react native icons and i'm using heart and hearto to switch when click on it
here is the code:
state = {
localAdversiment: [
{
title: "Ecloninear 871",
image: require("../../assets/images/truck_image.png"),
year: "2015",
type: "Truck",
status: "new",
price: "$ 2000",
heart: "hearto"
}
Here it function which is called when heart icon pressed
handleFavourite = index => {
const { heart } = this.state.localAdversiment[index];
this.setState(
{
heart: "heart"
}
);
};
here is the heart icon code
<TouchableOpacity onPress={() => this.handleFavourite(index)}>
<Icon
name={item.heart}
type={"AntDesign"}
style={{ fontSize: 18 }}
/>
</TouchableOpacity>
kindly help me how to update heart as heart instead of hearto when clicked
You can do it easily by following approach
state = {
localAdversiment: [
{
id: 0,
title: "Ecloninear 871",
image: require("../../assets/images/truck_image.png"),
year: "2015",
type: "Truck",
status: "new",
price: "$ 2000",
heart: "hearto",
selected: false
}
}
now in onPress do this
handleFavourite = (item) => {
const { id } = item;
this.setState({
localAdvertisement: this.state.localAdvertisement.map((item) => {
if(item.id === id){
return {
...item,
selected: !item.selected
}
}
return item
})
})
};
Now render like this
<TouchableOpacity onPress={() => this.handleFavourite(item)}>
<Icon
name={item.selected ? "heart" : 'hearto'}
type={"AntDesign"}
style={{ fontSize: 18 }}
/>
</TouchableOpacity>
Hope it will help you
Edit this function as follows:
handleFavourite = index => {
let updatedlocalAdversimentStates = this.state.localAdversiment;
updatedlocalAdversimentStates[index].heart = "heart";
this.setState(
{
localAdversiment: updatedlocalAdversimentStates
}
);
};

Props not being displayed in new route

I've been trying to learn React Native but it has been tougher than I thought. I can't create a simple "master-detail" app (and I couldn't find a good, simple tutorial explaining how to do it either).
I've managed to display a list of categories. After clicking one, it should display the category name + the list of items from this:
const data = [{
"category": "Fruits",
"items": [{
"name": "Apple",
"icon": "apple.png"
}, {
"name": "Orange",
"icon": "orange.png"
}]
}, {
"category": "Vegetables",
"items": [{
"name": "Lettuce",
"icon": "lettuce.png"
}, {
"name": "Mustard",
"icon": "mustard.png"
}]
}];
On my main class, I managed to display a list of categories:
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) =>
<Text onPress={this.onPressItem.bind(this, rowData.category)}>
{rowData.category}
</Text>}
/>
In my onPressItem I have the following:
onPressItem(category) {
this.props.navigator.push({
name: 'DetailView',
component: DetailView,
passProps: {
category
}
});
}
In my detail view, the category name is not being displayed:
class DetailView extends Component {
render() {
return (
<View style={ styles.container }>
<Text>Category: { this.props.category }</Text>
<TouchableHighlight onPress={ () => this.props.navigator.pop() }>
<Text>GO Back</Text>
</TouchableHighlight>
</View>
);
}
}
I'd really appreciate if someone can help me with this. It's probably something silly I'm doing wrong. Creating this simple thing can't be that hard. :/
Full code
I found a solution. I was making a mistake when rendering the view:
return React.createElement(
route.component,
{ navigator },
{...route.passProps}
);
The right way is:
return React.createElement(
route.component,
{ navigator, ...route.passProps }
);
Thanks to mehcode for helping me out.

Categories