I have made a call to my api using useEffect
and stored the array of items using useState
hook but I'm finding it difficult to render those items into a custom component which will also have the data passed.
Here's my react snippets:
export default function CreateCast() {
const [open, setOpen] = useState(false);
const [bibleCastItems, setBibleCastItems] = useState([]);
const classes = useStyles();
const fabStyle = {
bottom: 50.0,
right: 30.0,
position: "fixed"
};
useEffect(()=>{
async function fetchData(){
var items = await APIService.getAllBibleCasts();
// console.log(items);
// console.log(items.data.bibleCasts);
setBibleCastItems([items.data.bibleCasts]);
// items.data.bibleCasts.length > 0 ? setBibleCastItems([items.data.bibleCasts])
// : setBibleCastItems([]);
}
fetchData();
}, []
);
// console.log('bibleCastItems length ' + bibleCastItems.length);
return (
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<Card plain>
<CardHeader plain color="primary">
<div className={classes.container}>
<div className={classes.left}>
<h4 className={classes.cardTitleWhite}>All BibleCasts</h4>
<p className={classes.cardCategoryWhite}>
Powered by our friends from <b>Unicorn Tech Consultants</b>{" "}
</p>
</div>
</div>
</CardHeader>
<CardBody>
{
bibleCastItems.map((item, index) => <CastItem key={index} bibleCast={item[index]}/>) // this is where I'm facing issue
// bibleCastItems.map((item, index) => {
// console.log(item);
// setMyItem(item);
// return <div key={index}>{index}</div>
// })
}
<div className={classes.right}>
<Fab style={fabStyle} onClick={handleClickOpen}>
<AddIcon />
</Fab>
<UploadFormDialog
open={open}
handleClose={handleClose}
/>
</div>
</CardBody>
</Card>
</GridItem>
</GridContainer>
);
function handleClickOpen(){
setOpen(true);
};
function handleClose(){
setOpen(false);
};
}
Here's my state from browser view: [![state view][1]][1]
How do I map this state to be a list of components? I'm confused about it
As you can see, I'm using a dialog to create new items and close the dialog once the request is successful. I have one doubt here, how do I tell the main component hosting the dialog that the new data has been fetched and should be added to the state?
My main question here is how to map the items in state to return a list of <CastItem />
component
CastItem Component Snippet
export default function CastItem(props) {
let {bibleCast} = props;
const classes = useStyles();
return <GridContainer>
<GridItem xs={12} sm={6} md={4}>
<Card>
<CardHeader color="info" stats icon>
<CardIcon color="info">
<Streams />
</CardIcon>
</CardHeader>
<CardBody>
<h3 className={classes.cardTitle}>{bibleCast.title}</h3>
<p className={classes.cardCategory}> Reinhard Bonnke</p>
</CardBody>
</Card>
</GridItem>
</GridContainer>
}
CastItem.propTypes = {
bibleCast: PropTypes.object.isRequired,
}
JSON Response from API in console:
[![json response][2]][2]
If you were to create a state variable to represent this response as a list and display that list, how would you go about it, using hooks. Thank you. [1]: https://i.stack.imgur.com/QkthN.png [2]: https://i.stack.imgur.com/8Hf11.png
Mistake you are doing is in CreateCast component, form api you are already getting an array again you are passing it inside an array, so it is coming as nested array
Do like this
useEffect(()=>{
async function fetchData(){
var items = await APIService.getAllBibleCasts();
setBibleCastItems(items.data.bibleCasts);
}
fetchData();
}, []
);
For Maping do like this
{
bibleCastItems.map((item, index) => <CastItem key={index} bibleCast={item}/>)
}
// For question how to update parent from child follow below
There are two ways you can set data in a parent component, one is refetch from the api or pass from children to parent and update the state there
I have an example here how to update parent and children,to add names to a list,name list state is maintained in parent component here and child will pass back value to parent by adding name
import { useState } from "react";
import Child from "./Child";
export default function Parent() {
const [list, setList] = useState(["ram"]);
const handleAddName = (name) => {
if (name) {
setList([name, ...list]);
// or you can refetch the list from api here
}
};
return (
<div>
<div style={{ float: "left" }}>
<h1>I am a parent Component</h1>
<ul>
{list &&
list.map((item) => {
return <li key={item}>{item}</li>;
})}
</ul>
</div>
<Child handleSubmit={handleAddName} />
</div>
);
}
Child
import { useState } from "react";
export default function Child(props) {
const [name, setName] = useState("");
const updateNameList = (name) => {
if (name) {
props.handleSubmit(name);
//reset field after data is sent
// you can also save data here making post request respective api
setName("");
}
};
return (
<div style={{ float: "right" }}>
<h1>I am a Child Component</h1>
<p> Add names below</p>
<br />
<input value={name} onChange={(e) => setName(e.target.value)} />
<button onClick={() => updateNameList(name)}>Add</button>
</div>
);
}
refer to this codesand box
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.