Warning: React does not recognize the `PaperComponent` prop on a DOM element - javascript

I have simple modal using material ui 'Modal', i want to make it draggable, so user could move modal whereever they want simply by dragging, so i used 'Draggable' from react draggable, but i'm getting this error: Warning: React does not recognize the PaperComponent prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase papercomponent instead. If you accidentally passed it from a parent component, remove it from the DOM element.
what am i doing wrong ?
codesandbox:
https://codesandbox.io/s/draggabledialog-material-demo-forked-srw9yn?file=/demo.js
code:
import * as React from "react";
import Button from "#mui/material/Button";
import { Modal, Box } from "#material-ui/core";
import { Close } from "#material-ui/icons";
import Paper from "#mui/material/Paper";
import Draggable from "react-draggable";
export default function DraggableDialog() {
const [open, setOpen] = React.useState(false);
function PaperComponent(props) {
return (
<Draggable
handle="#draggable-dialog-title"
cancel={'[class*="MuiDialogContent-root"]'}
>
<Paper {...props} />
</Draggable>
);
}
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" onClick={handleClickOpen}>
Open draggable dialog
</Button>
<Modal
open={open}
onClose={handleClose}
PaperComponent={PaperComponent}
// aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
aria-labelledby="draggable-dialog-title"
>
<div>
<form
style={{
width: "360px",
color: "white",
display: "flex",
flexDirection: "column",
backgroundColor: "#1E2328"
}}
>
<div
style={{
backgroundColor: "black",
margin: "0",
display: "flex",
alignItems: "center",
height: "56px",
width: "360px",
color: "white",
justifyContent: "space-between"
}}
m={2}
>
<Box
style={{
color: "#E9ECEC",
fontSize: "21px"
}}
>
Countries{" "}
</Box>
<button
style={{ color: "white" }}
onClick={handleClose}
aria-label="close-settings-popup"
>
<Close />
</button>
</div>
<div style={{ height: "100%" }}>
<div>
Country Name
<p>Germany</p>
<p>France</p>
</div>
</div>
</form>
</div>
</Modal>
</div>
);
}

Modal component does not recognize PaperComponent that you passing to it as prop,
if you only want modal to be draggable modify your code like so:
import * as React from "react";
import Button from "#mui/material/Button";
import { Modal, Box } from "#material-ui/core";
import { Close } from "#material-ui/icons";
import Paper from "#mui/material/Paper";
import Draggable from "react-draggable";
export default function DraggableDialog() {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" onClick={handleClickOpen}>
Open draggable dialog
</Button>
<Modal
open={open}
onClose={handleClose}
// aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
aria-labelledby="draggable-dialog-title"
>
<Draggable>
<div>
<form
style={{
width: "360px",
color: "white",
display: "flex",
flexDirection: "column",
backgroundColor: "#1E2328"
}}
>
<div
style={{
backgroundColor: "black",
margin: "0",
display: "flex",
alignItems: "center",
height: "56px",
width: "360px",
color: "white",
justifyContent: "space-between"
}}
m={2}
>
<Box
style={{
color: "#E9ECEC",
fontSize: "21px"
}}
>
Countries{" "}
</Box>
<button
style={{ color: "white" }}
onClick={handleClose}
aria-label="close-settings-popup"
>
<Close />
</button>
</div>
<div style={{ height: "100%" }}>
<div>
Country Name
<p>Germany</p>
<p>France</p>
</div>
</div>
</form>
</div>
</Draggable>
</Modal>
</div>
);
}
https://codesandbox.io/s/draggabledialog-material-demo-forked-sx2npc?file=/demo.js

Related

delete button does not read id if modal added in ReactJS

I have created a CRUD application and successfully it is performing all the operations.
But when I try to create a modal so that it shows up a warning either to delete the id or not on clicking delete. And If I try to delete a particular id from the modal I'm unable to delete the selected item, else it is deleted the latest id in the list.
What might be the problem that is making me not delete a particular id from the list only when creating a modal.
Help me how I can make it work.
This is the button to open the warning modal:
const [open, setOpen] = useState(false);
const toggle = () => setOpen(!open);
<button onClick={toggle}>
<MdIcons.MdDelete color='black' fontSize="1.3rem"/>delete</button>
This is the modal that opens after clicking delete:
<Modal isOpen={open} toggle={toggle}>
<ModalHeader toggle={toggle}>Warning</ModalHeader>
<ModalBody>Are you sure to delete this id from the list...</ModalBody>
<ModalFooter>
<Button onClick={() => onDelete(data.id)}>YES</Button>
<Button onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
In the above modal I have give the onclick event for button YES to delete the id selected, but the delete functionality is not working when I use it on a modal.
These are the button functionalities:
const getData = () => {
axios.get(`https://62c45bb0abea8c085a73b996.mockapi.io/Reactcrud`)
.then((getData) => {
setAPIData(getData.data);
})
}
const onDelete = (id) => {
axios.delete(`https://62c45bb0abea8c085a73b996.mockapi.io/Reactcrud/${id}`)
.then(() => {
getData();
})
}
Please help me how I can achieve the functionality of deleting the particular id after modal opens, and let me know if you need any more details regarding my code.
I am new to react, i don't know if my explanation will be correct, my theory is that the problem was this: You were rendering the modal for every record, and only the last modal remained.
I put the modal outside the loop, and i declared a useState to track the selected id to delete, it worked =D
Read.js :
import axios from "axios";
import React, { useEffect, useState } from "react";
import { Table, Button, List, Popup, Grid, Icon, Dropdown, Menu, Header } from "semantic-ui-react";
import { useNavigate, Link } from "react-router-dom";
import * as MdIcons from "react-icons/md";
import * as AiIcons from "react-icons/ai";
import * as FiIcons from "react-icons/fi";
import { Modal, ModalFooter, ModalHeader, ModalBody } from "reactstrap";
import SideMenu from "../SideMenu/SideMenu";
function Read() {
const [APIData, setAPIData] = useState([]);
const [idToDelete, setIdToDelete] = useState(0);
useEffect(() => {
axios.get(`https://62c45bb0abea8c085a73b996.mockapi.io/Reactcrud`).then((response) => {
console.log(response.data);
setAPIData(response.data);
});
}, []);
const setData = (data) => {
let {
id,
image,
companyName,
email,
companyNumber,
uniqueNumber,
lineofBusiness,
companyRevenue,
openingTime,
closingTime,
discount,
rating,
address1,
address2,
pincode,
area,
city,
state,
country,
} = data;
localStorage.setItem("ID", id);
localStorage.setItem("Image", image);
localStorage.setItem("Email", email);
localStorage.setItem("Company Name", companyName);
localStorage.setItem("Company Number", companyNumber);
localStorage.setItem("Unique Number", uniqueNumber);
localStorage.setItem("Line of Business", lineofBusiness);
localStorage.setItem("Company Revenue", companyRevenue);
localStorage.setItem("Opening Time", openingTime);
localStorage.setItem("Closing Time", closingTime);
localStorage.setItem("Discount", discount);
localStorage.setItem("Rating", rating);
localStorage.setItem("Address1", address1);
localStorage.setItem("Address2", address2);
localStorage.setItem("Pincode", pincode);
localStorage.setItem("Area", area);
localStorage.setItem("City", city);
localStorage.setItem("State", state);
localStorage.setItem("Country", country);
};
const getData = () => {
axios.get(`https://62c45bb0abea8c085a73b996.mockapi.io/Reactcrud`).then((getData) => {
setAPIData(getData.data);
});
};
const onDelete = () => {
axios
.delete(`https://62c45bb0abea8c085a73b996.mockapi.io/Reactcrud/${idToDelete}`)
.then(() => {
navigate("/company/list");
toggle();
})
.then(() => {
getData();
});
};
let navigate = useNavigate();
const addUser = () => {
navigate("/company/create");
};
const [open, setOpen] = useState(false);
const toggle = () => setOpen(!open);
const [search, setSearch] = useState("");
return (
<>
<div className="container-fluid">
<div className="row">
<div className="col-lg-12" style={{ marginLeft: "-11px" }}>
<SideMenu />
</div>
</div>
<div className="row">
<div className="col-lg-3"></div>
<div className="col-lg-6">
<Button primary style={{ width: "150px", height: "40px" }} onClick={addUser}>
Add Company
</Button>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search by any Category"
style={{
position: "absolute",
width: "260px",
height: "40px",
marginLeft: "285px",
border: "none",
fontSize: "15px",
padding: "8px",
borderRadius: "20px 20px 20px 20px",
}}
/>
<table style={{ width: "700px", height: "200px" }}>
<thead style={{ margin: "50px" }}>
<tr>
<th style={{ textAlign: "center" }}>List of Companies</th>
</tr>
</thead>
{APIData.filter((data) =>
Object.values(data).some((value) => value.toLowerCase().includes(search.toLowerCase()))
).map((data, id) => {
return (
<>
<tbody key={id}>
<li
style={{
minHeight: "140px",
borderRadius: "5px",
margin: "20px 0px",
listStyle: "none",
padding: "25px",
backgroundColor: "white",
boxShadow: "0 0 20px 0px rgba(0,0,0,0.2)",
}}
>
<tr>
<Link to="/company/view">
<button
style={{
background: "transparent",
border: "none",
color: "blue",
}}
onClick={() => setData(data)}
>
{data.companyName}
</button>
</Link>
</tr>
<tr>{data.companyNumber}</tr>
<tr>{data.uniqueNumber}</tr>
<tr>{data.lineofBusiness}</tr>
</li>
<div
style={{
position: "absolute",
marginLeft: "580px",
marginTop: "-120px",
}}
>
<Dropdown
icon={
<AiIcons.AiOutlineEllipsis
style={{
color: "black",
fontSize: "1.3rem",
marginTop: "15px",
marginLeft: "30px",
border: "1px solid black",
width: "30px",
height: "30px",
borderRadius: "50%",
}}
/>
}
pointing="top right"
>
<Dropdown.Menu>
<Dropdown.Item icon="edit" text="Edit">
<Link to="/company/edit">
<button
onClick={() => setData(data)}
style={{
background: "transparent",
border: "none",
}}
>
<FiIcons.FiEdit color="black" fontSize="1.3rem" /> Edit
</button>
</Link>
</Dropdown.Item>
<Dropdown.Item icon="delete" text="Delete">
<button
onClick={() => {
setIdToDelete(data.id);
toggle();
}}
style={{
background: "transparent",
border: "none",
}}
color="red"
>
<MdIcons.MdDelete color="black" fontSize="1.3rem" />
delete
</button>
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>
</tbody>
</>
);
})}
</table>
<Modal isOpen={open} toggle={toggle}>
<ModalHeader toggle={toggle}>Warning</ModalHeader>
<ModalBody>Are you sure to delete this id from the list...</ModalBody>
<ModalFooter>
<Button color="red" onClick={onDelete}>
Okay
</Button>
<Button color="primary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
</div>
</div>
</>
);
}
export default Read;

React is only passing the last object in my array to a component

I have a react component where I map through a list of clients and display each client in a card.
return (
<div className='VolunteerClientsTab'>
{volunteerClients && volunteerClients.map((client) => (
<React.Fragment key={client.id}>
<div className='VolunteerClientsTab__card'>
<Avatar style={{ alignSelf: 'center', marginTop: '.5rem' }}>{client.first_name[0]}{client.last_name[0]}</Avatar>
<h2>{client.first_name} {client.last_name}</h2>
<h4>Details</h4>
<p><AiOutlineMail style={iconStyles} /> {client.email}</p>
<p><AiOutlinePhone style={iconStyles} /> {formatPhoneNumber(client.contact_number)}</p>
<h4 style={{ marginTop: '1rem' }}>Actions</h4>
<p onClick={handleOpenClientNeedsModal} className='hover-underline'><BiDonateHeart style={iconStyles} />View Needs</p>
<p className='hover-underline'><HiOutlineDocumentReport style={iconStyles} />Write Report</p>
<p className='hover-underline'><FiVideo style={iconStyles} />Contact Client</p>
</div>
<ClientNeeds open={openClientNeedsModal} handleClose={handleCloseClientNeedsModal} client={client} />
</React.Fragment>
))}
</div>
)
};
ClientNeeds is a component that renders an MUI modal to display additional client information. I am passing it the client object within the loop but when I open the modal only the client of the last index in the volunteerClients array was passed to all the modal components. Does anyone have any idea why this is happening?
ClientNeeds component
import React from 'react';
import Box from '#mui/material/Box';
import Modal from '#mui/material/Modal';
import PropTypes from 'prop-types';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
const ClientNeeds = ({ open, handleClose, client }) => {
return (
<div>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<h2>{client.email}</h2>
</Box>
</Modal>
</div>
)
};
ClientNeeds.propTypes = {
open: PropTypes.bool,
handleClose: PropTypes.func,
client: PropTypes.object
};
export default ClientNeeds;
MY SOLUTION
Passing the client onClick to an additional global state object and passing that state object to the modal,
const [selectedClient, setSelectedClient] = useState(null)
also only rendering the clientNeedsModal is there is an object in that state.
<div className='VolunteerClientsTab'>
{volunteerClients && volunteerClients.map((client) => (
<React.Fragment key={client.id}>
<div className='VolunteerClientsTab__card'>
<Avatar style={{ alignSelf: 'center', marginTop: '.5rem' }}>{client.first_name[0]}{client.last_name[0]}</Avatar>
<h2>{client.first_name} {client.last_name}</h2>
<h4>Details</h4>
<p><AiOutlineMail style={iconStyles} /> {client.email}</p>
<p><AiOutlinePhone style={iconStyles} /> {formatPhoneNumber(client.contact_number)}</p>
<h4 style={{ marginTop: '1rem' }}>Actions</h4>
<p onClick={() => handleOpenNeeds(client)} className='hover-underline'><BiDonateHeart style={iconStyles} />View Needs</p>
<p className='hover-underline'><HiOutlineDocumentReport style={iconStyles} />Write Report</p>
<p className='hover-underline'><FiVideo style={iconStyles} />Schedule Meeting</p>
</div>
{selectedClient ? (
<ClientNeeds open={openClientNeedsModal} handleClose={handleCloseClientNeedsModal} client={selectedClient} />
) : null}
</React.Fragment>
))}
</div>
const handleCloseClientNeedsModal = () => {
setSelectedClient(null)
setOpenClientNeedsModal(false);
}
const handleOpenNeeds = (client) => {
setSelectedClient(client)
handleOpenClientNeedsModal()
}
This allows me to pass any individual object within my array to the modal component as originally desired

useRef takes full control of an outer component instead of the component being used in

I am creating a Appbar with material UI. When I use a custom hook. to control the child component it also controls the whole parent component...
My purpose is to use this hook to disappear the component whenever a click is made outside of the component
Here is my custom hook
useListener.js
import { useEffect, useState, useRef } from "react";
export const useListener = (active, ref) => {
ref = useRef();
const [open, setOpen] = useState((active = false));
useEffect(() => {
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
setOpen(!open);
return;
}
}
// Bind the event listener
document.body.addEventListener("click", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.body.removeEventListener("click", handleClickOutside);
};
}, [open, ref]);
return [open, ref];
};
when I use it in the component by destructing it with
const [open, ref] = useListener()
and use it inside the component, I set open to appear and disappear the component, with CSS..
display: open ? 'block' : 'none'
Now when I use this component in which this hook is being used, When I click on this component it appears, and when I click outside of the component (any where else in the body) it disappears, which is totally fine...
But the issue is when I click on the parent component in with this component is being used it also makes appear this child component...
Here is my child component...
Profile.js
import React from "react";
import Paper from "#mui/material/Paper";
import Box from "#mui/material/Box";
import cover from "../assets/cover.webp";
import profilepic from "../assets/profilepic.webp";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
import { LogoutIcon } from "../assets/LogoutIcon";
import { ChangePasswordIcon } from "../assets/ChangePasswordIcon";
import { useListener } from "../../../hooks/useListener";
const logout = () => {
localStorage.removeItem("authorization");
localStorage.removeItem("user");
localStorage.removeItem("permissions");
window.location.reload(false);
};
const Profile = () => {
const [open, profileRef] = useListener();
console.log(profileRef.current);
return (
<Box
ref={profileRef}
sx={{
display: open ? "inline" : "none",
width: "190px",
}}
>
<Paper elevation={2}>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<img src={cover} alt="Cover" style={{ width: "190px" }}></img>
<img
src={profilepic}
alt="Profile"
style={{ height: "62px", width: "62px", borderRadius: "50%" }}
></img>
<Typography variant="button" display="block" gutterBottom>
Username
</Typography>
<Button>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<ChangePasswordIcon sx={{ height: "18px", width: "18px" }} />
<Typography variant="body1" gutterBottom>
Change password
</Typography>
</Box>
</Button>
<Button onClick={logout}>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<LogoutIcon sx={{ width: "16px", height: "16px" }} />
<Typography variant="body1" gutterBottom>
Logout
</Typography>
</Box>
</Button>
</Box>
</Paper>
</Box>
);
};
export default Profile;
And this is the parent component...
TopbarContents.js
import React, { useState } from "react";
import Box from "#mui/material/Box";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
import profilepic from "../assets/profilepic.webp";
import Profile from "./Profile";
export const TopbarContents = () => {
const [profileActive, toggleProfile] = useState(false);
const openProfile = () => {
toggleProfile(true);
};
return (
<Box sx={{ width: "100%" }}>
<Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
}}
>
<Box sx={{ flexGrow: 1 }}>
<Typography
sx={{ color: "#494343" }}
variant="h6"
noWrap
component="div"
>
Dashboard
</Typography>
</Box>
<Box
sx={{
height: "45px",
width: "160px",
borderRadius: 2,
display: "flex",
flexDirection: "column",
justifyContent: "center",
border: "1px solid #e0e0e0",
pl: "8px",
}}
>
<Typography sx={{ color: "#2E4299", pt: 1 }} variant="caption">
Case study
</Typography>
<Typography sx={{ color: "#494343" }} variant="overline">
Trial ID: NC48023194
</Typography>
</Box>
<Button
color="guava"
variant="contained"
size="medium"
sx={{ fontFamily: "Poppins", mr: 6, ml: 3 }}
>
Case Study
</Button>
<Button onClick={openProfile}>
<img
src={profilepic}
alt="Profile"
style={{ height: "62px", width: "62px", borderRadius: "50%" }}
></img>
</Button>
</Box>
<Box
sx={{
display: profileActive ? "inline" : "none",
flexDirection: "column",
}}
>
<Profile />
</Box>
</Box>
);
};

How to lock the position of close button with paper component of modal in material ui for responsive screen?

I had built a cards page where I'm rendering multiple cards on a page. On clicking each card a popup card renders aka modal component but my close button is not responsive to the card.
Here is an image. See the button is going the wrong position when I open it to inspect.
Here is my link to complete code at codesandbox.
imagePopup.js modal component with close button
import React from "react";
import { makeStyles } from "#material-ui/core";
import Modal from "#material-ui/core/Modal";
import Backdrop from "#material-ui/core/Backdrop";
import Fade from "#material-ui/core/Fade";
import ActionButton from "./ActionButton";
import { CloseOutlined } from "#material-ui/icons";
const useStyles = makeStyles((theme) => ({
modal: {
display: "flex",
alignItems: "center",
justifyContent: "center"
},
paper: {
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[5]
},
actionBtn: {
position: "absolute",
right: 555,
top: 85
}
}));
export default function ImagePopup(props) {
const classes = useStyles();
const { openModal, setOpenModal, handleOpen, handleClose, img } = props;
return (
<div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={openModal}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Fade in={openModal}>
<div>
<div className={classes.actionBtn}>
<ActionButton
// to edit icon functionality
color="secondary"
onClick={handleClose}
>
<CloseOutlined fontSize="small" />
</ActionButton>
</div>
<div className={classes.paper}>
<img src={img} height="500" />
</div>
</div>
</Fade>
</Modal>
</div>
);
}
Adjust your actionBtn bloc style like this:
actionBtn: {
position: "absolute",
marginLeft: 352,
marginTop: -5,
borderRadius: 0,
'& > button': {
background: "transparent" // If you want button to be transparent
}
}

Passing values from database to flip cards in JS React

I am trying to pass my API value to the Flippy card to dynamically render image and the word displayed on flip.
I am struggling with something I thought would be easy: I have an API where I call back an image link and a word to populate the flip cards. I want to dynamically render my flip cards to the page using that data, but right now my image link and the word are hard coded and I don't know to pass my API call values to the component. API works and correctly returns links and words; hard coded flip card also works with no issues and functions as intended. I believe I have to implement props and pass it somehow to the const DefaultCardContents- thanks so much for taking a stab at it.
I tried implemeneting props but I am unsure how to pass them to the constant
THIS IS MY FLASHCARD COMPONENT
import React, { Component } from 'react';
import Flippy, { FrontSide, BackSide } from './../lib';
import Button from 'react-bootstrap/Button';
import './style.css';
const FlippyStyle = {
width: '200px',
height: '200px',
textAlign: 'center',
color: '#FFF',
fontFamily: 'sans-serif',
fontSize: '30px',
justifyContent: 'center'
}
const DefaultCardContents = ({ children }) => (
<React.Fragment>
<FrontSide
style={{
backgroundColor: 'white',
display: 'flex',
alignItems: 'center',
flexDirection: 'column'
}}
>
<img
src="https://parent.guide/wp-content/uploads/2014/08/Banana-baby-food-recipes.jpg"
style={{ maxWidth: '100%', maxHeight: '100%' }}
/>
<span
style={{
fontSize: '12px',
position: 'absolute',
bottom: '10px',
width: '100%'
}}>
{children}<br />
Hover over to show key word
</span>
</FrontSide>
<BackSide
style={{
backgroundColor: '#EB6864',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column'
}}>
<h1>Banana</h1>
<span
style={{
fontSize: '12px',
position: 'absolute',
bottom: '10px',
width: '100%'
}}>
{children}<br />
<Button variant="success">Success</Button>
<Button variant="outline-warning">Warning</Button>
</span>
</BackSide>
</React.Fragment>);
const FlippyOnHover = ({ flipDirection = 'vertical' }) => (
<Flippy
flipOnHover={true}
flipDirection={flipDirection}
style={FlippyStyle}
>
<DefaultCardContents>
</DefaultCardContents>
</Flippy>
);
class Flashcard extends Component {
constructor(props) {
super(props);
this.state = {
isFlipped: false
}
}
render() {
return (
<div className="App">
<div style={{ display: 'flex', flex: '1 0 200px', justifyContent: 'space-around', 'flex-wrap': 'wrap' }}>
<FlippyOnHover flipDirection="horizontal" />
</div>
</div>
);
}
}
export default Flashcard;
THIS IS MY API CALL AND PAGE RENDER
import React, { Component } from "react";
import Flashcard from "../components/Flashcard";
import API from "../utils/API";
class Flashcards extends Component {
state = {
flashcards: [],
flashcardName: "",
flashcardImage: "",
flipped: false
};
componentDidMount() {
this.loadFlashcards();
};
loadFlashcards = () => {
API.getFlashcards()
.then(res => {
// console.log(res.data);
this.setState({ flashcards: res.data, flashcardName: "", flashcardImage: "" })
// console.log("flashhhhhhhhhh" + JSON.stringify(this.state.flashcards));
})
.catch(err => console.log(err));
};
flipped = () => {
console.log(this.state)
if (this.state.flipped === false) {
this.setState({ flipped: true })
}
}
render() {
return (
<div>
{this.state.flashcards.length ? (
<div>
{this.state.flashcards.map(flashcards => (
<div key={flashcards._id} >
<Flashcard/>
</div>
))}
</div>
) : (
<h3>No Results to Display</h3>
)}
</div>
)
}
}
export default Flashcards;
Expected result is a dynamically generated array of cards base don API
You need to modify your Flashcard component to accept props for the title and the URL for the image, assuming that is in the data returned from the API.
In your map, pass the values to the Flashcard, something like:
{this.state.flashcards.map(flashcard => (
<div key={flashcard._id}>
<Flashcard
title={flashcard.title}
imageUrl={flashcard.image}
/>
</div>
))}
Edit:
Looks like your are using the react-flippy library, so you don't need to manage what state the flash card is in.
Crudly, your FlashCard component could look something like:
import React, { Component } from "react";
import Flippy, { FrontSide, BackSide } from "./../lib";
import Button from "react-bootstrap/Button";
import "./style.css";
const FlippyStyle = {
width: "200px",
height: "200px",
textAlign: "center",
color: "#FFF",
fontFamily: "sans-serif",
fontSize: "30px",
justifyContent: "center"
};
const CardContents = ({ title, imageUrl }) => (
<React.Fragment>
<FrontSide
style={{
backgroundColor: "white",
display: "flex",
alignItems: "center",
flexDirection: "column"
}}
>
<img
src={imageUrl}
style={{ maxWidth: "100%", maxHeight: "100%" }}
/>
<span
style={{
fontSize: "12px",
position: "absolute",
bottom: "10px",
width: "100%"
}}
>
<br />
Hover over to show key word
</span>
</FrontSide>
<BackSide
style={{
backgroundColor: "#EB6864",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column"
}}
>
<h1>{title}</h1>
<span
style={{
fontSize: "12px",
position: "absolute",
bottom: "10px",
width: "100%"
}}
>
<br />
<Button variant="success">Success</Button>
<Button variant="outline-warning">Warning</Button>
</span>
</BackSide>
</React.Fragment>
);
class Flashcard extends Component {
render() {
return (
<div>
<div
style={{
display: "flex",
flex: "1 0 200px",
justifyContent: "space-around",
"flex-wrap": "wrap"
}}
>
<Flippy flipOnHover={true} flipDirection='horizontal' style={FlippyStyle}>
<CardContents imageUrl={this.props.imageUrl} title={this.props.title}/>
</Flippy>
</div>
</div>
);
}
}
export default Flashcard;

Categories