I have a React dApp for a smart contract that I have made. In one of the routes of the application which I go by clicking a button named "All Cryptonauts" as seen in the screenshow below, I try to call all of the minted NFT's of my smart contract. I can successfully get them and map them all, but at first, nothing comes up.
However, after clicking the "All Cryptonauts" button again, all of the intended data gets shown.
Below, there are the codes of my page. I think my problem is with rendering, so I have made some research and someone said that they avoid to manually rerender and fix an identical issue with removing the key attributes from the HTML codes, but it didn't work for me and there were errors in the console when I removed the keys. I can't use this.setState here, too. Can anyone help me with the right way to do what I want please? Thank you!
export const AllCryptonauts = (props) => {
const web3 = window.web3;
var [currentAccount, setCurrentAccount] = useState("0x0");
let [model, setModel] = useState([]);
let lastMintJson;
let supply = [];
let myNFTs = [];
useEffect(() => {
window.ethereum.on('chainChanged', (_chainId) => checkChainID());
window.ethereum.on('accountsChanged', (_accounts) => loadBlockchainData());
checkChainID();
return () => { }
}, [currentAccount])
async function checkChainID() {
const networkId = await web3.eth.net.getId();
if (networkId !== 4) {
props.history.push("/")
} else {
loadBlockchainData();
}
}
async function loadBlockchainData() {
window.web3 = new Web3(window.ethereum);
const accounts = await web3.eth.getAccounts();
setCurrentAccount(accounts[0]);
loadContract();
}
async function loadContract() {
if (currentAccount.length > 5) {
const ContractObj = impContract;
supply = await ContractObj.methods.totalSupply().call();
setAllMints(supply);
}
}
async function setAllMints(supply) {
for (var i = 1; i <= parseInt(supply, 10); i++) {
lastMintJson = "https://cors-anywhere.herokuapp.com/https://nftornek.000webhostapp.com/cryptonauts/json/" + i + ".json";
let res = await axios.get(lastMintJson);
res.data.imagelink = "https://nftornek.000webhostapp.com/cryptonauts/image/" + i + ".png"
myNFTs.push(res.data);
}
setModel(setNFTModel(myNFTs));
}
function setNFTModel(jsonObj) {
for (var i = 0; i < jsonObj.length; i++) {
model[i] = {
dna: jsonObj[i].dna,
name: jsonObj[i].name,
edition: jsonObj[i].edition,
imagelink: jsonObj[i].imagelink,
attributes: jsonObj[i].attributes
};
}
return model;
}
return (
<div>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}><img src="https://nftornek.000webhostapp.com/frontend/cnlogo.png" width='500' height='180' alt=""></img></div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<button className="regularButton divide" onClick={MintPage}>Mint</button>
<button className="regularButton divide" onClick={MyCryptonauts}>My Cryptonauts</button>
<button className="regularButton divide" onClick={AllCryptonauts}>All Cryptonauts</button>
<button className="regularButton divide" onClick={Disconnect}>Disconnect</button>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}><p className="accountText">Current Account: {currentAccount}</p></div>
{model.map((item, i) => (
<div key={i} style={{ display: 'flex', justifyContent: 'center', marginBottom: '30px', height: '350px' }}>
<div style={{ width: '350px', border: '2px solid #38495a', borderRadius: '5px' }}><img src={item.imagelink} alt=""></img>
</div>
<div style={{ width: '300px', padding: '10px', border: '2px solid #38495a', borderRadius: '4px', backgroundColor: 'rgba(56, 73, 90, 0.25)', color: '#38495a' }}><b>ID: {item.edition}<br></br> Name: {item.name}</b>
<table className="tableClass t1">
<tbody>
{item.attributes.map((attr, j) => (
<tr key={'attr' + ' ' + j}>
<td key={1}>{attr.trait_type}:</td>
<td key={2}>{attr.value}</td>
</tr>
))}
</tbody>
</table></div>
</div>
))}
</div>
)
}
Try something like this:
{model && model.map((item, i) => (
I think as well that your data(state) is not available at the moment that the page is rendered
I have fixed the error by following this answer by ray from Why is useState not triggering re-render?:
You're calling setNumbers and passing it the array it already has. You've changed one of its values but it's still the same array, and I suspect React doesn't see any reason to re-render because state hasn't changed; the new array is the old array.
One easy way to avoid this is by spreading the array into a new array:
setNumbers([...old])
Now it works.
Related
I am using react-dropzone in reactjs project, while uploading images the preview shows a broken link with a error "net::ERR_FILE_NOT_FOUND". it is working fine in firefox.
in there own site it is not working in chrome you can check here https://react-dropzone.js.org/#section-previews. please guide what should I do in this.
"I think this error is because URL.createObjectURL
import {useDropzone} from 'react-dropzone';
const thumbsContainer = {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
marginTop: 16
};
const thumb = {
display: 'inline-flex',
borderRadius: 2,
border: '1px solid #eaeaea',
marginBottom: 8,
marginRight: 8,
width: 100,
height: 100,
padding: 4,
boxSizing: 'border-box'
};
const thumbInner = {
display: 'flex',
minWidth: 0,
overflow: 'hidden'
};
const img = {
display: 'block',
width: 'auto',
height: '100%'
};
function Previews(props) {
const [files, setFiles] = useState([]);
const {getRootProps, getInputProps} = useDropzone({
accept: 'image/*',
onDrop: acceptedFiles => {
setFiles(acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}
});
const thumbs = files.map(file => (
<div style={thumb} key={file.name}>
<div style={thumbInner}>
<img
src={file.preview}
style={img}
/>
</div>
</div>
));
useEffect(() => {
// Make sure to revoke the data uris to avoid memory leaks
files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
return (
<section className="container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
<aside style={thumbsContainer}>
{thumbs}
</aside>
</section>
);
}
<Previews />
add return before files like this return () => files.forEach(file => URL.revokeObjectURL(file.preview)); inside useEffect
Currently the useEffect is revoking all blob URLs when files state update but we want the blob URLs to be available until component unmount.
Just change the useEffect implementation to:
useEffect(() => {
// Make sure to revoke the data uris to avoid memory leaks
return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
This will revoke the blob URLs on unmount and will allow you to see the previews when the component is mounted.
first, Thank you for entering like here
i want to be able to use like this code, this code is rendering in react component but second code doesn't work ..
That's what i worder sir.
function forFourMultiplyFour(_pictures) {
if (_pictures.length === 0) {
return '';
}
return <div
style={{ display: 'flex', justifyContent: 'center' }}>{_pictures.map((el) => {
return <div style={{ margin: '5px' }}>
<Img key={el.id} src={el.src} alt="picture"></Img>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>{el.title}</div>
<div>생성일자</div>
</div>
</div>;
})}</div>;
}
function makeHowManyPage(count) {
// 태그안에 함수로 또 다른 태그를 감싼다음에 forFourMultiplyFour로 한 것처럼 렌더링할 것을 return 했는데
// 안되서 state을 배열로 만들어서
return <div
className="makeHowManyPage"
style={{ display: 'flex', justifyContent: 'center' }}>
{() => {
for (let i = 1; i <= count; i++) {
return <div>{i}</div>
}
}}
</div>
}
and then i do render like this
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import dummyPictures from '../../../dummyDate';
function Gallery() {
const [forRenderingOne, setForRenderingOne] = useState(<div></div>);
const [forRenderingTwo, setForRenderingTwo] = useState(<div></div>);
const [forRenderingThree, setForRenderingThree] = useState(<div></div>);
const [forRenderingFour, setForRenderingFour] = useState(<div></div>);
const [pageCount, setPageCount] = useState(<div>1</div>);
const [_temp, set_Temp] = useState(['안녕하세요', '안녕하세요', '안녕하세요', '안녕하세요'])
// 애초에 4개씩 받아서 뿌릴 것
function forFourMultiplyFour(_pictures) {
if (_pictures.length === 0) {
return '';
}
return <div
style={{ display: 'flex', justifyContent: 'center' }}>{_pictures.map((el) => {
return <div style={{ margin: '5px' }}>
<Img key={el.id} src={el.src} alt="picture"></Img>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>{el.title}</div>
<div>생성일자</div>
</div>
</div>;
})}</div>;
}
function makeHowManyPage(count) {
// 태그안에 함수로 또 다른 태그를 감싼다음에 forFourMultiplyFour로 한 것처럼 렌더링할 것을 return 했는데
// 안되서 state을 배열로 만들어서
return <div
className="makeHowManyPage"
style={{ display: 'flex', justifyContent: 'center' }}>
{() => {
for (let i = 1; i <= count; i++) {
return <div>{i}</div>
}
}}
</div>
}
useEffect(() => {
// 서버에서 줄때 무조건 객체 16개가 든 배열이 응답해와야 정상작동되는 코드다..
setPageCount(makeHowManyPage(5))
setForRenderingOne(forFourMultiplyFour(dummyPictures.pictures.slice(0, 4)));
setForRenderingTwo(forFourMultiplyFour(dummyPictures.pictures.slice(4, 8)));
setForRenderingThree(forFourMultiplyFour(dummyPictures.pictures.slice(8, 12)));
setForRenderingFour(forFourMultiplyFour(dummyPictures.pictures.slice(12)));
}, []);
return (
<div>
{/* {forRenderingOne}
{forRenderingTwo}
{forRenderingThree}
{forRenderingFour} */}
{()=>{ return <div>'안녕하세요'</div>}}
</div>
)
}
export default Gallery
const Img = styled.img`
width: 15vw;
height: 20vh;
`
As stated this code snippet not working,
function makeHowManyPage(count) {
// 태그안에 함수로 또 다른 태그를 감싼다음에 forFourMultiplyFour로 한 것처럼 렌더링할 것을 return 했는데
// 안되서 state을 배열로 만들어서
return <div
className="makeHowManyPage"
style={{ display: 'flex', justifyContent: 'center' }}>
{() => {
for (let i = 1; i <= count; i++) {
return <div>{i}</div>
}
}}
</div>
}
Have a look at this snippet returning div not array,
for (let i = 1; i <= count; i++) {
return <div>{i}</div>
}
map works differently.
Consider changing this to,
function makeHowManyPage(count) {
// 태그안에 함수로 또 다른 태그를 감싼다음에 forFourMultiplyFour로 한 것처럼 렌더링할 것을 return 했는데
// 안되서 state을 배열로 만들어서
let array = [];
for (let i = 1; i <= count; i++) {
array.push(<div key={i}>{i}</div>);
}
return (
<div
className="makeHowManyPage"
style={{ display: "flex", justifyContent: "center" }}
>
{array}
</div>
);
}
Then usage,
export default function App() {
// declaration
let elements = makeHowManyPage(5);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{elements}
</div>
);
}
I don't understand what you exactly wanted, I just write some code that I expected to solve your problem.
I hope it can help your problem though it is not the best solution.
First, I divide Gallery component into two components including your forFourMultiplyFour function.
(I don't have dummy pictures, so I used a picture list api for this.)
Second, as windowsill's comment, write simple value for the useState initial value. I think you only need two values, pages and images array.
Usually people get the image list changing page and offset value not slicing image array. (If I have a wrong idea, please let me know.)
So I just change page state when clicking button.
For 4*4 image arrangement, I used flex property.
import React, { useState, useEffect } from "react";
import axios from "axios";
import ForFourMultiplyFour from "./ForFourMultiplyFour";
function Gallery() {
const [page, setPage] = useState(1);
const [images, setImages] = useState([]);
const URL = "https://picsum.photos/v2/list";
const LIMIT = 16;
useEffect(() => {
async function fetchImages() {
const { data } = await axios.get(`${URL}?page=${page}&limit=${LIMIT}`);
setImages(data);
}
fetchImages();
}, [images, page]);
useEffect(() => {
setPage(page)
}, [page])
return <ForFourMultiplyFour images={images} page={page} setPage={setPage} />;
}
export default Gallery;
import styled from "styled-components";
function ForFourMultiplyFour({ images, setPage, page }) {
const handlePage = (param) => {
if (param === "plus") {
setPage(page + 1);
} else {
if (page === 1) return;
setPage(page - 1);
}
};
if (images.length < 1) return <></>;
return (
<>
<ButtonWrapper>
<Button onClick={() => handlePage("minus")}>prev</Button>
<Button onClick={() => handlePage("plus")}>next</Button>
</ButtonWrapper>
<div
style={{
display: "flex",
justifyContent: "center",
flexWrap: "wrap"
}}
>
{images.map((el) => {
return (
<div style={{ margin: "5px", flex: "1 1 20%" }} key={el.id}>
<Img key={el.id} src={el.download_url} alt="picture"></Img>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div>생성일자</div>
</div>
</div>
);
})}
</div>
</>
);
}
const Img = styled.img`
width: 15vw;
height: 20vh;
`;
const ButtonWrapper = styled.div`
display: flex;
`;
const Button = styled.button`
cursor: pointer;
`;
export default ForFourMultiplyFour;
You can see the result through this Code Sandbox link.
If it is not a solution that you wanted, please comment me. Then I'll try to help you using another solution.
Objective is to have an array with captured pokemons if user clicks on the input and an array of not-captured pokemons if user un-clicks the input. I've managed to filter out the pokemon when it's no longer captured and have it in the not-captured array but I can't seem to delete that pokemon from the old captured array.
Eg. If I click on "bulbasaur", "charmender", "squirtle", I get them all in the captured array. If I then remove one of them, I correctly get the removed one in the not-captured array but I can't seem to delete it from the previous captured array.
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import PokemonIcon from "./PokemonIcon";
const PokemonCard = ({ pokemon, capturedPkm, setCapturedPkm, notCapturedPkm, setNotCapturedPkm }) => {
const [label, setLabel] = useState('Not captured')
const toggleCaptured = (checked, id) => {
const pokemonName = { id: pokemon.id, name: pokemon.name }
if (checked && id === pokemon.id) {
setCapturedPkm([...capturedPkm, pokemonName])
setLabel('Captured!')
} else {
setLabel('Not captured!')
setNotCapturedPkm([...notCapturedPkm, pokemonName])
if (checked === false) {
let newArr = [...capturedPkm]
let pkmRemoved = newArr.filter((el, i) => el.id === id)
let newArrPkm = newArr.splice(pkmRemoved, 1)
console.log('newArr',newArrPkm, 'pkmRemoved', pkmRemoved)
setCapturedPkm(newArrPkm)
}
}
}
useEffect(() => {
console.log('captured', capturedPkm, 'not captured', notCapturedPkm)
}, [capturedPkm, notCapturedPkm])
return (
<>
<div
className="pokemon-card"
style={{
height: "250px",
maxWidth: "250px",
margin: "1rem",
boxShadow: "5px 5px 5px 4px rgba(0, 0, 0, 0.3)",
cursor: "pointer",
}}
>
<Link
to={{ pathname: `/pokemon/${pokemon.id}` }}
style={{ textDecoration: "none", color: "#000000" }}
state={{ pokemon: pokemon, capturedPkm }}
>
<div
style={{
padding: "20px",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<PokemonIcon img={pokemon.sprites?.['front_default']} />
</div>
</Link>
<div style={{ textAlign: "center" }}>
<h1>{pokemon.name}</h1>
<label>
<input type="checkbox"
defaultChecked={false}
value={pokemon.name}
onChange={(e) => toggleCaptured(e.target.checked, pokemon.id)} />
<span style={{ marginLeft: 8, cursor: 'pointer' }}>
{label}
</span>
</label>
</div>
</div>
<div></div>
</>
);
};
export default PokemonCard;
I guess you forgot to update the notCapturedPkm array. You could try something like this :
if (checked && id === pokemon.id) {
setCapturedPkm([...capturedPkm, pokemonName])
// Update this array, by removing the selected pokemon
setNotCapturedPkm([...notCapturedPkm.filter(pkm => pkm.id !== pokemon.id)])
setLabel('Captured!')
}
I'm working on creating a chart that will show set percentages of a user-inputted number. For example the user enters "200" and the chart would show "100% = 200, 95% = 190, etc.". The percentages on the chart will stay the same, it'll be just the input number and the percentage results that will change. hopefully that makes sense.
Here is the code for the chart:
import React, { useState } from 'react';
const issStyles = {
chart: {
display: 'flex',
flexDirection: 'row',
margin: '20px',
},
percentBox: {
background: '#E7E7E7',
borderRadius: '10px',
padding: '5px',
display: 'flex',
justifyContent: 'center',
width: '200px',
fontSize: '24px',
},
percentResultBox: {
background: '#E7E7E7',
borderRadius: '10px',
padding: '5px',
display: 'flex',
justifyContent: 'center',
width: '200px',
fontSize: '24px',
},
line: {
padding: '5px',
justifyContent: 'center',
fontSize: '24px',
},
}
export default function PercentChart(props) {
const [ percent ] = useState(props.percent)
const [ percentResult ] = useState(props.percentResult)
return (
<div style={issStyles.chart}>
<div style={issStyles.percentBox}>
{percent}
</div>
<div style={issStyles.line}>
----------
</div>
<div style={issStyles.percentResultBox}>
{percentResult}
</div>
</div>
)
};
Here is the code for the page it is being called in:
import React from 'react';
import HeaderButton from '../../components/HeaderButton';
import PercentChart from '../../components/PercentChart';
const issStyles = {
PRNumber: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: '20px',
fontFamily: 'PT Sans Caption',
fontSize: '18px',
},
Space: {
margin: '10px',
},
PRChart: {
background: '#C4C4C4',
width: '80%',
borderRadius: '10px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
margin: '0 auto',
},
};
export default function PercentPage() {
return (
<div>
<HeaderButton exerciseName="Movement 1" />
<div style={issStyles.PRNumber}>
PR:
<input type="number" placeholder="Enter current PR" style={issStyles.Space}/>
</div>
<div style={issStyles.PRChart}>
<PercentChart percent="100%" percentResult="100"/>
<PercentChart percent="95%" percentResult="95"/>
<PercentChart percent="90%" percentResult="90"/>
<PercentChart percent="85%" percentResult="85"/>
<PercentChart percent="80%" percentResult="80"/>
<PercentChart percent="75%" percentResult="75"/>
<PercentChart percent="70%" percentResult="70"/>
<PercentChart percent="65%" percentResult="65"/>
<PercentChart percent="60%" percentResult="60"/>
<PercentChart percent="55%" percentResult="55"/>
</div>
</div>
);
};
Here is a screenshot of what the page currently looks like:
Basically, what I want to happen is the user would enter a number in the "Enter current PR" input field, and the numbers on the right of the chart would automatically update to whatever is the corresponding percentage of that number. I know right now I have the numbers hard coded and not associated with the input field at all, and that's what I need help on mainly. I'm new to coding so any additional tips/corrections would be wonderful. Thank you!
Runnable Code Snippet
const { useEffect, useState } = React;
const { Container, Table, Form } = ReactBootstrap;
function App() {
const [pr, setPr] = useState(100);
const [levels, setLevels] = useState([]);
useEffect(() => {
const arr = [];
let percentage = 100;
while (percentage > 0) {
arr.push([percentage, (pr * percentage) / 100]);
percentage -= 5;
}
setLevels(arr);
}, [pr]);
return (
<Container>
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Label>PR</Form.Label>
<Form.Control
type="input"
placeholder="100"
value={pr}
onChange={(e) => setPr(e.target.value)}
/>
</Form.Group>
</Form>
<Table striped bordered hover>
<thead>
<tr>
<th>Percent</th>
<th>Result</th>
</tr>
</thead>
<tbody>
{levels.map((level) => (
<tr key={level[0]}>
<td>{level[0]}%</td>
<td>{level[1]}</td>
</tr>
))}
</tbody>
</Table>
</Container>
);
}
// Render it
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-bootstrap#next/dist/react-bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div id="react"></div>
Example Code Before Mangling for Snippet
import React, { useEffect, useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Container from "react-bootstrap/Container";
import Table from "react-bootstrap/Table";
import Form from "react-bootstrap/Form";
export default function App() {
const [pr, setPr] = useState(100);
const [levels, setLevels] = useState([]);
useEffect(() => {
const arr = [];
let percentage = 100;
while (percentage > 0) {
arr.push([percentage, (pr * percentage) / 100]);
percentage -= 5;
}
setLevels(arr);
}, [pr]);
return (
<Container>
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Label>PR</Form.Label>
<Form.Control
type="input"
placeholder="100"
value={pr}
onChange={(e) => setPr(e.target.value)}
/>
</Form.Group>
</Form>
<Table striped bordered hover>
<thead>
<tr>
<th>Percent</th>
<th>Result</th>
</tr>
</thead>
<tbody>
{levels.map((level) => (
<tr key={level[0]}>
<td>{level[0]}%</td>
<td>{level[1]}</td>
</tr>
))}
</tbody>
</Table>
</Container>
);
}
I used React Bootstrap for formatting. The idea is you have the form field for the user to enter a number. When it changes, the onEffect fires and parses the input. Then it calculates the percentages and places them in an array. The array is set as the "levels" and we use the map method to render the table.
I'm trying to utilize this example in order to create a calendar that lists out the events in the current month, I have this part working, but what I have yet to figure out is how to make it so that the user can click the event name and it would take them to that event page.
So per that example, if they click on one of the birthdays, it would take them to an events page where they could see more about that birthday.
Currently, my events page is being rendered using this function:
renderEvents() {
const {events} = this.state
this.state.events = {};
let eventItems = this.state.eventGet.map(event => {
console.log(event.id)
if(typeof(events[moment(event.date).date()]) !== "undefined") {
events[moment(event.date).date()].push(event.name)
} else {
events[moment(event.date).date()] = [event.name]
}
});
function renderDay(day) {
const date = day.getDate();
const dateStyle = {
position: 'absolute',
color: 'lightgray',
bottom: 0,
right: 0,
fontSize: 20,
};
const containerStyle = {
margin:'2px',
border: '1px solid #3a87ad',
borderRadius: '3px',
position: 'relative',
display: 'block',
cursor: 'pointer'
};
const textStyle = {
fontSize: '0.8em',
textAlign: 'left',
margin: '1.5px',
}
const cellStyle = {
height: 150,
width: 160,
position: 'relative',
};
return (
<div style={cellStyle}>
<div style={dateStyle}>{date}</div>
{events[date] &&
events[date].map((name, i) => (
<div onClick={() => this.props.history.push('/organizations/' + this.props.match.params.orgID + '/events' + i)} key={i} style={containerStyle}>
<div style={textStyle}> {name} </div>
</div>
))}
</div>
);
}
return (
<div>
<Grid component="section" className="section--center" shadow={0} noSpacing>
<Cell col={12}>
<FABButton style={{margin: '10px', float: "right"}} colored ripple onClick={() => this.props.history.push('/organizations/' + this.props.match.params.orgID + '/events')}>
<Icon name="add" />
</FABButton>
</Cell>
<DayPicker
canChangeMonth={true}
className="Birthdays"
renderDay={renderDay}
/>
</Grid>
</div>
);
}
The current problem is within the sub-function, renderDay which is called by the DayPicker component that gets the events associated with the day. When I try to push to the history property, it errors out and says that I cannot read property 'history' from undefined, which makes sense because we did not pass the history property to that function.
Can someone help me in figuring out how to modify that sub-function so that the onClick event on the div will take a user to that events page?
and says that I cannot read property 'history' from undefined
Make sure your renderDay function is bound to the correct this:
<DayPicker
canChangeMonth
className="Birthdays"
renderDay={renderDay.bind(this)}
/>