feat(react-crud): add delete and home page
This commit is contained in:
parent
174cd6383a
commit
23e30ac60e
|
@ -13,6 +13,7 @@
|
|||
* [React Router](https://www.w3schools.com/react/react_router.asp)
|
||||
* [React form](https://www.w3schools.com/react/react_forms.asp)
|
||||
* [React CRUD](https://www.freecodecamp.org/news/how-to-perform-crud-operations-using-react/)
|
||||
* [React Router](https://www.digitalocean.com/community/tutorials/how-to-handle-routing-in-react-apps-with-react-router)
|
||||
* [React setup with webpack for beginners](https://dev.to/deepanjangh/react-setup-with-webpack-for-beginners-2a8k)
|
||||
* [Production](https://webpack.js.org/guides/production/)
|
||||
* [Setup Development and Production Environment for React App](https://medium.com/freestoneinfotech/setup-development-and-production-environment-for-react-app-397c4cc9e382)
|
||||
|
|
|
@ -1,13 +1,45 @@
|
|||
import React from 'react';
|
||||
//BrowserRouter: base configuration
|
||||
//Route: configure specific routes and wrap component
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Routes,
|
||||
Route,
|
||||
Link
|
||||
} from 'react-router-dom';
|
||||
|
||||
import Home from './components/home';
|
||||
import Create from './components/create';
|
||||
import Read from './components/read';
|
||||
import Update from './components/update';
|
||||
import Delete from './components/delete';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<Create />
|
||||
<Read />
|
||||
<Update />
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<div className="wrapper">
|
||||
{/*h1: global page title*/}
|
||||
{/*template: wrapper and h1 is rendered on every page*/}
|
||||
{/*TODO Navigation or header on every page?*/}
|
||||
<h1>App</h1>
|
||||
<Router>
|
||||
<div className="App">
|
||||
<ul>
|
||||
<li><Link to="/">Home</Link></li>
|
||||
<li><Link to="/create">Create</Link></li>
|
||||
<li><Link to="/read">Read</Link></li>
|
||||
<li><Link to="/update">Update</Link></li>
|
||||
<li><Link to="/delete">Delete</Link></li>
|
||||
</ul>
|
||||
<Routes>
|
||||
{/*exact: match the exact value with the URL*/}
|
||||
<Route exact path='/' element={< Home />}></Route>
|
||||
<Route exact path='/create' element ={<Create />}></Route>
|
||||
<Route exact path='/read' element={<Read />}></Route>
|
||||
<Route exact path='/update' element={<Update />}></Route>
|
||||
<Route exact path='/delete' element={<Delete />}></Route>
|
||||
</Routes>
|
||||
</div>
|
||||
</Router>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
import React, { useState } from 'react'
|
||||
import axios from 'axios';
|
||||
import axios from 'axios';
|
||||
|
||||
export default function Create() {
|
||||
const [name, setName] = useState('');
|
||||
const postData = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('name: '+name);
|
||||
axios.post(
|
||||
'http://85.223.94.182:65535/entities/create',
|
||||
{
|
||||
name:{name}
|
||||
//console.log('name: '+name);
|
||||
const url='http://83.223.94.182:65535/entities/create';
|
||||
//console.log('url: '+url);
|
||||
let data = new FormData();
|
||||
data.append('name',name);
|
||||
let config = {
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: url,
|
||||
data : data
|
||||
};
|
||||
axios.request(config)
|
||||
.catch((error)=>{
|
||||
console.error('create:axios error: '+error);
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<p>Create</p>
|
||||
<h1>Create</h1>
|
||||
<form onSubmit={postData}>
|
||||
<label>
|
||||
Enter name (input:{name}):
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import React, { useState } from 'react'
|
||||
import axios from 'axios';
|
||||
export default function Delete() {
|
||||
const [id, setId] = useState('');
|
||||
const postData = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('id: '+id);
|
||||
/*
|
||||
const url='http://83.223.94.182:65535/entities/'+id+'/delete';
|
||||
console.log('url: '+url);
|
||||
let config = {
|
||||
method: 'delete',
|
||||
maxBodyLength: Infinity,
|
||||
url: url,
|
||||
headers: {}
|
||||
};
|
||||
axios.request(config)
|
||||
.catch((error) => {
|
||||
console.error('create:axios error: '+error);
|
||||
});
|
||||
*/
|
||||
/*
|
||||
let config = {
|
||||
method: 'delete',
|
||||
maxBodyLength: Infinity,
|
||||
url: 'http://83.223.94.182:65535/entities/20/delete',
|
||||
headers: { }
|
||||
};
|
||||
axios.request(config)
|
||||
.then((response) => {
|
||||
console.log('rsp.data: '+response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
*/
|
||||
axios.delete('http://83.223.94.182:65535/entities/20/delete')
|
||||
.catch(error => {
|
||||
console.error('There was an error!', error);
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<h1>Delete</h1>
|
||||
<form onSubmit={postData}>
|
||||
<label>
|
||||
Enter id (input:{id}):
|
||||
<input
|
||||
placeholder='Id'
|
||||
type="text"
|
||||
value={id}
|
||||
onChange={(e) => setId(e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
//destructure props
|
||||
const Hello = ({msg}) => {
|
||||
return (
|
||||
<>
|
||||
<div>{msg}</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Hello
|
||||
|
||||
Hello.propTypes = {
|
||||
msg: PropTypes.string,
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function Home (){
|
||||
return <h1>Home</h1>
|
||||
};
|
|
@ -1,23 +1,41 @@
|
|||
import React, {useEffect,useState} from 'react'
|
||||
import axios from 'axios';
|
||||
import {Link} from 'react-router-dom';
|
||||
|
||||
export default function Read() {
|
||||
//create state containing incoming data array
|
||||
const [apiData,setApiData]=useState([]);
|
||||
//useEffect Hook, cos we need data when app loads
|
||||
useEffect(()=>{
|
||||
//get data
|
||||
const getData=()=>{
|
||||
axios.get('http://83.223.94.182:65535/entities/info')
|
||||
.then((response)=>{
|
||||
setApiData(response.data);
|
||||
});
|
||||
};
|
||||
//create state containing incoming data array
|
||||
const [apiData,setApiData]=useState([]);
|
||||
//useEffect Hook, cos we need data when app loads
|
||||
useEffect(()=>{
|
||||
//console.log('Read calls useEffect()');
|
||||
getData();
|
||||
},[]);
|
||||
//handle update button
|
||||
const setData=(data)=>{
|
||||
console.log('data: '+data);
|
||||
};
|
||||
//handle delete button
|
||||
const onDelete=(id)=>{
|
||||
console.log('read:onDelete() id: '+id);
|
||||
getData()
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<p>Read</p>
|
||||
<h1>Read</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Name</th>
|
||||
<th>Update</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -29,6 +47,24 @@ export default function Read() {
|
|||
>
|
||||
<td>{value[0]}</td>
|
||||
<td>{value[1]}</td>
|
||||
<td>
|
||||
<Link to='/update'>
|
||||
<button
|
||||
type="button"
|
||||
onClick={()=>setData(data)}
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
onClick={()=>onDelete(data.id)}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -1,8 +1,52 @@
|
|||
import React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import axios from 'axios';
|
||||
export default function Update() {
|
||||
const [name, setName] = useState('');
|
||||
const [id, setId] = useState('');
|
||||
const postData = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('id: '+id);
|
||||
console.log('name: '+name);
|
||||
const url='http://83.223.94.182:65535/entities/'+id+'/update';
|
||||
console.log('url: '+url);
|
||||
let data = new FormData();
|
||||
data.append('name',name);
|
||||
let config = {
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: url,
|
||||
data : data
|
||||
};
|
||||
axios.request(config)
|
||||
.catch((error) => {
|
||||
console.error('create:axios error: '+error);
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<p>Update</p>
|
||||
<h1>Update</h1>
|
||||
<form onSubmit={postData}>
|
||||
<label>
|
||||
Enter id (input:{id}):
|
||||
<input
|
||||
placeholder='Id'
|
||||
type="text"
|
||||
value={id}
|
||||
onChange={(e) => setId(e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Enter name (input:{name}):
|
||||
<input
|
||||
placeholder='Name'
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import React from 'react';
|
||||
import Hello from '../components/hello';
|
||||
import '../style.css';
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<Hello />
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,3 +0,0 @@
|
|||
h1 { color: red; }
|
||||
h2 { color: green; }
|
||||
h3 { color: blue; }
|
|
@ -10,10 +10,9 @@
|
|||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"axios": "1.3.4",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-router-dom": "^6.10.0"
|
||||
"react-router-dom": "6.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.18.13",
|
||||
|
@ -4581,14 +4580,6 @@
|
|||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
|
||||
|
@ -4958,16 +4949,6 @@
|
|||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -5084,11 +5065,6 @@
|
|||
"react": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
|
||||
|
@ -9849,11 +9825,6 @@
|
|||
"boolbase": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
|
||||
|
@ -10118,16 +10089,6 @@
|
|||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -10218,11 +10179,6 @@
|
|||
"scheduler": "^0.23.0"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "1.3.4",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
"react-dom": "18.2.0",
|
||||
"react-router-dom": "6.10.0"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue