I'm am new to React and this is my first project.
I am trying to pass the id (which comes from item.id
) of a transaction located in my Summary
functional component to my EditTransaction
functional component.
It is giving me this error: TypeError: Cannot read property 'props' of undefined
I've tried:
But it does not seem to work either...
App.js
import './App.css';
import {BrowserRouter as Router, Switch, Route, Link, Redirect} from 'react-router-dom';
import Home from "./views/Home";
import Summary from './views/Summary';
import Profile from './views/Profile';
import Groups from './views/Groups';
import About from './views/About';
import Transaction from './views/Transaction';
import Signin from "./components/Signin";
import EditTransaction from "./views/EditTransaction";
import 'bootstrap/dist/css/bootstrap.min.css';
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/Signin" component={Signin} />
<Route exact path="/About" component={About} />
<Route exact path="/Profile" component={Profile} />
<Route exact path="/Groups" component={Groups} />
<Route exact path="/Summary" component={Summary} />
<Route exact path="/Transaction" component={Transaction} />
<Route exact path="/EditTransaction/:id" component={EditTransaction} />
</Switch>
</Router>
</div>
);
}
export default App;
Summary.js
import React, { useEffect, useState } from 'react';
import {NavLink} from 'react-router-dom';
import Button from '@material-ui/core/Button';
import { Redirect } from 'react-router-dom';
import EditTransaction from '../views/EditTransaction';
import SigninNavBar from '../components/SigninNavBar';
function Summary(){
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [trans, setTrans] = useState([]);
const [signin, setSignin] = useState({signin:localStorage.getItem('token') ? true : false});
const [details, setDetails] = useState({username:"", email:"", password:""});
console.log("Token: " + localStorage.getItem('token'));
const options = {
method: 'GET',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': `JWT ${localStorage.getItem('token')}`
}
};
useEffect(() => {
fetch("http://34.94.76.5/api/transactions/get/", options)
.then(response => {
if (response.status !== 200) {
console.log(response.status);
setError(response);
}
response.json().then(data => {
setIsLoaded(true);
setTrans(data);
});
});
}, []);
if (error) {
return (<Redirect to="/Signin" />);
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<SigninNavBar />
<table className="table">
<thead>
<th>ID</th>
<th>Member ID</th>
<th>Created</th>
<th>Category</th>
<th>Description</th>
<th>Amount</th>
</thead>
{trans.map(item => (
<tbody>
<tr>
<td> {item.id} </td>
<td> {item.member_id} </td>
<td> {item.created} </td>
<td> {item.category} </td>
<td> {item.description} </td>
<td> {item.amount} </td>
<td>
<Button variant="contained" color="primary">
<NavLink className="text-white" to={{ pathname:`/EditTransaction/${item.id}`, state:{id: item.id} }}>
Edit
</NavLink>
</Button>
</td>
</tr>
</tbody>
))}
</table>
</div>
);
}
}
export default Summary;
EditTransaction.js
import React, { useEffect, useState } from 'react';
import { Redirect } from 'react-router-dom';
import moment from 'moment';
import SigninNavBar from '../components/SigninNavBar.js';
import Summary from '../views/Summary.js';
var currentDate = moment().format("MM/DD/YYYY HH:mm:ss");
function EditTransaction(props) {
const [error, setError] = useState(null);
const [trans, setTrans] = useState([]);
const [tranUpdated, settranUpdated] = useState({id:0, member_id:'', category:'', description:'', amount:0});
const [isLoaded, setIsLoaded] = useState(false);
const [tran, setTran] = useState([]);
//GET request for specific id
const optionsGET = {
method: 'GET',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': `JWT ${localStorage.getItem('token')}`
}
};
useEffect(() => {
fetch("http://34.94.76.5/api/transactions/get/" + this.props.location.state + "/", optionsGET)
.then(response => {
if (response.status !== 200) {
console.log(response.status);
setError(response);
}
response.json().then(data => {
setIsLoaded(true);
setTrans(data);
});
});
}, []);
//PUT request to API for transaction
const optionsPUT = {
method: 'PUT',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': `JWT ${localStorage.getItem('token')}`
},
body:JSON.stringify(tranUpdated)
}
const updateTransaction = e => {
e.preventDefault();
fetch("http://34.94.76.5/api/transactions/get/" + this.props.location.state + "/", optionsPUT)
.then((response) => console.log('reponse: ' + response.json()))
.then((message) => console.log('message: ' + message))
}
if (error) {
return (<Redirect to="/Signin" />);
} else{
return (
<div className="wrapper">
<SigninNavBar />
<form>
<h1>Update Transaction</h1>
{trans.map(item => (
<div className="form-horizantal">
<fieldset>
<div className="form-group row">
<label className="col-md-12"><p>{currentDate}</p></label>
</div>
<div className="form-group row">
<label className="col-md-12">
<p>Member ID {item.member_id}</p>
<input type="text" name="member_id" placeholder={item.member_id} onChange={e => settranUpdated({ ...tranUpdated, member_id: e.target.value })} />
</label>
</div>
<div className="form-group row">
<label className="col-md-12">
<p>Transaction ID</p>
<input type="text" name="id" placeholder={item.id} onChange={e => settranUpdated({ ...tranUpdated, id: e.target.value })} />
</label>
</div>
<div className="form-group row">
<label className="col-md-12">
<p>Category</p>
<input type="text" name="category" placeholder={item.category} onChange={e => settranUpdated({ ...tranUpdated, category: e.target.value })} />
</label>
</div>
<div className="form-group row">
<label className="col-md-12">
<p>Description</p>
<input type="text" name="description" placeholder={item.description} onChange={e => settranUpdated({ ...tranUpdated, description: e.target.value })} />
</label>
</div>
<div className="form-group row">
<label className="col-md-12">
<p>Amount</p>
<input type="text" name="amount" placeholder={item.amount} onChange={e => settranUpdated({ ...tranUpdated, amount: e.target.value })} />
</label>
</div>
</fieldset>
<button type="submit" onClick={updateTransaction}>Update</button>
</div>
))}
</form>
</div>
);
}
}
export default EditTransaction;
You shouldn't use the this
keyword in a function component
Consider changing this.props.location.state
to just props.location.state.id