fetching data from API and display it but I want display the information of corresponding selected data using radio button but not able to display the data when selecting radio button
if condition is not working in handleData()
so any one tell where I'm doing wrong
import React, {component, useStates} from 'react';
import axios from 'axios';
export default class Posts extends React.Component {
constructor(){
super();
this.handleData = this.handleData.bind(this);
this. state = {
details: [],
selected: [],
hndleres:[]
}
}
// pagination
componentDidMount() {
this.renderData();
this.displyhandleData();
}
renderData(){
axios.get(`https://jsonplaceholder.typicode.com/posts`)
.then(res => {
const details = res.data;
this.setState({ details });
})
}
renderList(){
return(this.state.details).map((data, index) =>{
const uID = data.userId
const ID = data.id
const Body =data.body
const Title = data.title
return(
<tr>
<td><input type="radio" name="details" value={ID} onChange={this.handleData}></input></td>
<td>{ID}</td>
<td>{uID}</td>
<td>{Title}</td>
<td>{Body}</td>
</tr>
)
} )
}
handleData = (e) => {
this.state.value = e.target.value;
//debugger;
console.log(e.target.value)
debugger;
if(e.target.value != '1')
{
debugger;
let url = 'https://jsonplaceholder.typicode.com/posts'
const data = { "ID": e.target.value }
const res= axios.get(url, data)
.then(res =>{
this.setState = ({ hndleres : res.data})
});
}
else{
this.displyhandleData();
}
}
displyhandleData(){
return(this.state.hndleres).map((datas,index) =>{
const uID = datas.userId
const ID = datas.id
const Body =datas.body
const Title = datas.title
return(
<tr>
<td><input type="radio" name="details" value={ID} onChange={this.handleData}></input></td>
<td>{ID}</td>
<td>{uID}</td>
<td>{Title}</td>
<td>{Body}</td>
</tr>
)
})
}
render() {
return (
<div>
<table className="table">
{ this.renderList()}
</table>
<table className="table">
{ this.displyhandleData()}
</table>
</div>
)
}
}
so any one tell me where I'm doing wrong
render data from api but not display data of selected radio button:
There are multiple issues in your code, like mutating state directly, passing params obj in axios, And overriding this.setState function instead of calling it. I have corrected a few. Have a look and let me know if this helps
import React from "react";
import axios from "axios";
export default class Posts extends React.Component {
constructor() {
super();
this.handleData = this.handleData.bind(this);
this.state = {
details: [],
selected: [],
hndleres: []
};
}
// pagination
componentDidMount() {
this.renderData();
this.displyhandleData();
}
renderData() {
axios.get(`https://jsonplaceholder.typicode.com/posts`).then(res => {
const details = res.data;
this.setState({ details });
});
}
renderList() {
return this.state.details.map((data, index) => {
const uID = data.userId;
const ID = data.id;
const Body = data.body;
const Title = data.title;
return (
<tr>
<td>
<input
type="radio"
name="details"
value={ID}
onChange={this.handleData}
></input>
</td>
<td>{ID}</td>
<td>{uID}</td>
<td>{Title}</td>
<td>{Body}</td>
</tr>
);
});
}
handleData = e => {
//debugger;
console.log(e.target.value);
debugger;
if (e.target.value != "1") {
debugger;
let url = "https://jsonplaceholder.typicode.com/posts";
const data = { userId: e.target.value };
axios.get(url, { params: data }).then(res => {
this.setState({ hndleres: res.data });
});
} else {
this.displyhandleData();
}
};
displyhandleData() {
return this.state.hndleres.map((datas, index) => {
const uID = datas.userId;
const ID = datas.id;
const Body = datas.body;
const Title = datas.title;
return (
<tr>
<td>
<input
type="radio"
name="details"
value={ID}
onChange={this.handleData}
></input>
</td>
<td>{ID}</td>
<td>{uID}</td>
<td>{Title}</td>
<td>{Body}</td>
</tr>
);
});
}
render() {
return (
<div>
<table className="table">{this.renderList()}</table>
<table className="table">{this.displyhandleData()}</table>
</div>
);
}
}
Related
Hi everone i have a issue or more over i want to know "How can i create a tree table kind off structure using the nested json". With out using any 3rd part lib/package
I have a nested json like below :
[
{
"id": 1,
"name": "VehicleData",
"owner": "admin",
"sub_details": [
{
"sub_name": "Lexus",
"sub_id": 4,
},
{
"sub_name": "BMW",
"sub_id": 3,
}
]
},
{
"id": 2,
"name": "Mobiles,
"owner": "admin",
"sub_details": [
{
"sub_name": "Apple",
"sub_id": 2,
}
]
},
{
"id": 3,
"name": "Laptop",
"owner": "admin",
"sub_details": []
}
]
What i have tried :-
import React, {useState, useEffect} from 'react';
import classes from './TableData.module.css';
const TableData = () => {
const [oldData, newData] = useState([]);
useEffect(() => {
fetchData();
}, []);
const Id = (dataId) => {
alert(dataId);
};
const Name = (dataName) => {
alert(dataName);
};
const fetchData = async () => {
try {
const response = await fetch('someapi/json');
const data = await response.json();
newData(data);
} catch (e) {
console.warn(e)
}
}
const DisplayData = oldData.map((data) => {
return (
<tr key={
data.id
}>
<td> {
data.id
} </td>
<td> {
data.name
} </td>
<td> {
data.owner
} </td>
<td>
<button onClick={
() => Id(data.id)
}>getId</button>
<button onClick={
() => Name(data.name)
}>getname</button>
</td>
</tr>
)
})
return (
<div>
<div>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>owner</th>
</tr>
</thead>
<tbody> {DisplayData} </tbody>
</table>
</div>
</div>
)
}
export default TableData;
what i have done :
I have created a table using json and also added button for getting the parent data
what i need and how can i do :
How can i add create the nested structure without using 3rd party plugins and also add button to each row .
How can i get the parent data and child data on each child row button click .
How can i able to toggle & keep open up the nested structure .
if any info url are there it will be great full ?
In React, you must break your data into components. Working with the data as is, in multi-level nesting, is considered bad design - see here for a detailed explanation.
With this in mind, I dedicated one component for each nesting level. This way, the row can manage its sub-row hidden state. Here's the final code - see full demo here - click the "toggle" button:
index.js:
import React, { useState, useEffect } from "react";
import "./styles.css"
const Table = () => {
const [items, setItems] = useState([]);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
const response = await fetch("./data.json");
const data = await response.json();
setItems(data);
} catch (e) {
console.warn(e);
}
};
return <div>
{
items.map((data) => {
return <TableData key={data.id} data={data} />
})
}
</div>;
};
const TableData = (props) => {
const data = props.data;
const [subHidden, setSubHidden] = useState(false);
const Id = (dataId) => {
alert(dataId);
};
const Name = (dataName) => {
alert(dataName);
};
const Toggle = () => {
setSubHidden(state => {
return !state;
});
};
return (
<div >
<span> {data.id} </span>
<span> {data.name} </span>
<span> {data.owner} </span>
<span>
<button onClick={() => Id(data.id)}>getId</button>
<button onClick={() => Name(data.name)}>getname</button>
<button onClick={() => Toggle()}>toggle</button>
</span>
<TableSubDetails
subDetails={data.sub_details}
style={{ display: subHidden ? 'none' : 'block'}}
/>
</div>
);
}
const TableSubDetails = (props) => {
const subDetails = props.subDetails;
return (
<div className="subData" style={props.style}>
{
subDetails.map((subData) => {
return <div key={subData.sub_id}>
<span> {subData.sub_id} </span>
<span> {subData.sub_name} </span>
</div>
})
}
</div>
);
}
export default Table;
styles.css:
.subData {
padding: 5px 15px;
}
Here is my version of the solution by updating your existing code with some logic
const TableData = () => {
const [oldData, newData] = useState([]);
const [id, setId] = useState({});
useEffect(() => {
fetchData();
}, []);
const Id = (dataId) => {
alert(dataId);
};
const Name = (dataName) => {
alert(dataName);
};
const fetchData = async () => {
try {
newData(jsonData);
} catch (e) {
console.warn(e);
}
};
const updateId = useCallback((dataId) => {
setId((prevState) => {
let updatedState = { ...prevState };
const hasId = updatedState[dataId] ? true : false;
if (hasId) {
delete updatedState[dataId];
} else {
updatedState = { ...updatedState, [dataId]: dataId };
}
return {
...updatedState
};
});
}, []);
const renderTableRows = useCallback(
(details, isChild = false) => {
let renderData = [];
details.forEach((detail) => {
const detailId = isChild ? detail["sub_id"] : detail["id"];
const name = isChild ? detail["sub_name"] : detail["name"];
const childData = (
<tr key={`${name}-${detailId}`}>
<td> {detailId} </td>
<td> {name} </td>
<td> {detail.owner} </td>
<td>
<button onClick={() => Id(detailId)}>getId</button>
<button onClick={() => Name(name)}>getname</button>
{detail.sub_details?.length > 0 && (
<button
onClick={() => {
updateId(detailId);
}}
>
{id[detailId] === detailId ? "Hide" : "Show"} child
</button>
)}
</td>
</tr>
);
renderData.push(childData);
if (id[detailId] === detailId && detail.sub_details?.length > 0) {
const childData = renderTableRows(detail.sub_details, true);
renderData = [...renderData, ...childData];
}
});
return renderData;
},
[id, updateId]
);
const DisplayData = useMemo(() => {
return renderTableRows(oldData);
}, [oldData, renderTableRows]);
return (
<div>
<div>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>owner</th>
</tr>
</thead>
<tbody> {DisplayData} </tbody>
</table>
</div>
</div>
);
};
export default TableData;
here is the example link.
Thanks
I need to click on the button to delete the line with the selected checkbox.
I don't know how to use the filter method. I read the documentation, but there is little information there. help me correct the code
class Table extends Component {
constructor(props) {
super(props);
this.state = {
droplets: [],
allSelected: false,
isChecked: false
}
this.toggleSelectAll = this.toggleSelectAll.bind(this);
this.toggleSelect = this.toggleSelect.bind(this);
this.handleChecked = this.handleChecked.bind(this);
**this.handleDelete = this.handleDelete.bind(this);**
}
async componentDidMount() {
const res = await fetch('http://api.npoint.io/324f4ca2cdd639760638');
const droplets = await res.json();
this.setState({ 'droplets': droplets })
}
toggleSelect(dropletToToggle) {
this.setState({isChecked: !this.state.isChecked});
this.setState((prevState) => {
const newDroplets = prevState.droplets.map((dplt) => {
if (dplt === dropletToToggle) {
return { ...dplt, checked: !dplt.checked };
}
return dplt;
});
return {
...prevState,
droplets: newDroplets,
allSelected: newDroplets.every((d) => !!d.checked)
};
});
}
toggleSelectAll() {
this.setState({isChecked: !this.state.isChecked});
this.setState((prevState) => {
const toggle = !prevState.allSelected;
const newDroplets = prevState.droplets.map((x) => ({
...x,
checked: toggle
}));
return {
...prevState,
droplets: newDroplets,
allSelected: toggle
};
});
}
handleChecked () {
this.setState({isChecked: !this.state.isChecked});
}
**handleDelete = isChecked => {
this.setState(state => {
const { droplets } = state;
const filteredDroplets = droplets.filter(item => item.id !== isChecked);
return {
droplets: filteredDroplets
};
});
};**
render() {
return (
<div className="body">
<div className="title">Таблица пользователей</div>
<table className="panel">
<Tablehead
toggleSelectAll={this.toggleSelectAll}
allSelected={this.state.allSelected}
/>
<tbody className="row">
<TableBody
droplets={this.state.droplets}
toggleSelect={this.toggleSelect}
/>
</tbody>
</table>
**<button className="button" onClick = {this.handleDelete} >Удалить выбранные</button>**
</div>
);
}
}
the second file in which the item to delete
const TableBody = ({ droplets, toggleSelect}) => {
return (
<>
{droplets.map((droplet, item) => (
<tr className={s.area} key={item.id} >
<td>
<Checkbox
handleClick={() => toggleSelect(droplet)}
isChecked={!!droplet.checked}
/>
</td>
<td>{droplet.num}</td>
<td>{droplet.first_name + " " + droplet.last_name}</td>
<td>{date_form(droplet.date_of_birth)}</td>
<td>{height_form(droplet.height)}</td>
<td>{weight_form(droplet.weight)}</td>
<td>{salary_form(droplet.salary)}</td>
<td>
<button type="submit" className={s.button}>
<Edit />
</button>
</td>
<td>
<button type="submit" className={s.button}>
<Trash />
</button>
</td>
</tr>
))}
</>
);
};
https://codesandbox.io/s/sweet-butterfly-0s4ff?file=/src/Table.jsx
I have altered your sandbox and added some functionality in order to delete the rows.
The comparison is based on full name but you can change it to whatever fits your needs.
https://codesandbox.io/s/keen-silence-i51wz
On your handleDelete function your filter condition seems wrong
Currently you have:
// Filters all droplets that have an id different to the value of isChecked.
const filteredDroplets = droplets.filter(item => item.id !== isChecked);
And it should be
// Returns all the droplets that are not checked
// Meaning that all the checked items are dropped from the array
const filteredDroplets = droplets.filter(item => !item.isChecked);
I'm using react to create a panel to add a new product. I've created a separate auto-complete class which is supposed to render an input element and a list of suggested autofill items underneath. The input element shows but not the autofill suggestions. Have a look at the code
Autofill class
import React, { Component } from "react";
import firebase from "../Firebase";
export default class AutoCompleteDistID extends Component {
constructor() {
super();
this.state = {
sellerName: [],
sellerId: [],
suggestions: [],
};
}
componentDidMount() {
var sellerRef = firebase.database().ref().child("Sellers");
sellerRef.once("value", (snapshot) => {
snapshot.forEach((childSnap) => {
var distrName = childSnap.val().sellerName;
var distrId = childSnap.val().sellerName.sellerId;
// var distrName = [{ name: data.sellerName }];
this.setState((prevState) => {
return {
sellerName: [...prevState.sellerName, distrName],
sellerId: [...prevState.sellerId, distrId],
suggestions: [...prevState.suggestions, distrName],
};
});
});
});
}
onTextChange = (e) => {
var sellerNames = [this.state.sellerName];
const value = e.target.value;
let newSuggestions = [];
if (value.length > 0) {
const regex = new RegExp(`^${value}`, "i");
newSuggestions = sellerNames.sort().filter((v) => regex.test(v));
}
this.setState(() => ({ newSuggestions }));
};
renderSuggestions() {
const newSuggestions = this.state.suggestions;
if (newSuggestions.length === 0) {
return null;
}
return (
<ul>
{newSuggestions.map((item) => (
<li>{item}</li>
))}
</ul>
);
}
render() {
return (
<div>
<input onChange={this.onTextChange} />
{this.renderSuggestions}
</div>
);
}
}
Main form
import React, { Component } from "react";
import firebase from "../Firebase";
import AutoCompleteDistID from "./AutoCompleteDistID";
export default class Products extends Component {
constructor() {
super();
this.state = {
description: "",
prodQty: "",
};
this.pushProduct = this.pushProduct.bind(this);
}
handleFormChange = (event) => {
const target = event.target;
const colName = target.name;
this.setState({
[colName]: event.target.value,
});
};
pushProduct() {
const userRef = firebase.database().ref().child("Users"); //Get reference to Users DB
const prodData = this.state;
userRef.push(prodData);
}
render() {
return (
<div>
<br />
<form style={{ border: "solid", borderWidth: "1px", width: "600px" }}>
<br />
<input
type="text"
value={this.state.prodQty}
placeholder="Available Quantity"
onChange={this.handleFormChange}
name="prodQty"
/>
<input
type="text"
value={this.state.description}
placeholder="Description"
onChange={this.handleFormChange}
name="description"
/>
<AutoCompleteDistID />
<br />
<br />
</form>
<button onClick={this.pushProduct} type="button">
Add Product
</button>
<br />
</div>
);
}
}
State variable is suggestions but you are setting newSuggestions.
onTextChange = (e) => {
var sellerNames = [this.state.sellerName];
const value = e.target.value;
let newSuggestions = [];
if (value.length > 0) {
const regex = new RegExp(`^${value}`, "i");
newSuggestions = sellerNames.sort().filter((v) => regex.test(v));
}
// HERE IS THE MISTAKE
this.setState(() => ({ suggestions: newSuggestions }));
};
In AutoCompleteDistID render method
render() {
return (
<div>
<input onChange={this.onTextChange} />
{this.renderSuggestions()}
</div>
);
}
Testing some things in React js and having some issues with some of my logic. I am trying to get value from inputs in a form then on submitting that form i want to take that object of input values and add them to my ctcList array. I am trying to use the es6 features of spread for concating my current newCtc state with my ctcList state. When i console log i get the newCtc values but then the ctcList array is empty. Any help is appreciated.
Thank you!
import React, { Component } from 'react';
import Contact from './Contact';
import TestData from './TestData';
class ContactList extends Component {
constructor(props){
super(props);
this.state = {
name: '',
test1:'',
test2:'',
newCtc:{},
ctcList:[],
arr: []
}
}
async componentDidMount() {
try{
const result = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await result.json()
this.setState({arr:data})
}catch(err){
console.log(err)
}
}
onChangeInput = (e)=>{
const target = e.target;
const name = target.name;
const value = target.value;
console.log(value)
this.setState({
[name]: value
});
}
newSubmit = (e) =>{
e.preventDefault();
this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}));
console.log(this.state.newCtc)
this.addContact();
this.clearInput();
console.log(this.state.newCtc);
}
addContact = ()=>{
this.setState({ ctcList:[ ...this.state.ctcList, this.state.newCtc] });
console.log(this.state.ctcList);
};
clearInput = ()=>{
this.setState({test1:'',test2:''});
this.setState(Object.assign(this.state.newCtc,{test1:'', test2:''}));
};
render() {
return (
<div>
<Contact firstName = {this.state.name} lastName='mcdaniel' phoneNumber = '585-721-3824' />
<input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>
<TestData data={this.state.arr} />
<form onSubmit = {this.newSubmit}>
<input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}
/>
<input type='text' name={'test2'} value={this.state.test2} onChange = {this.onChangeInput}
/>
<button type='submit'> submit </button>
</form>
</div>
)
}
}
export default ContactList;
Try this one, take notice on the callback function of setState
import React, { Component } from 'react';
class ContactList extends Component {
constructor(props){
super(props);
this.state = {
name: '',
test1:'',
test2:'',
newCtc:{},
ctcList:[],
arr: []
}
}
async componentDidMount() {
try{
const result = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await result.json()
this.setState({arr:data})
}catch(err){
console.log(err)
}
}
onChangeInput = (e)=>{
const target = e.target;
const name = target.name;
const value = target.value;
this.setState({
[name]: value
});
}
newSubmit = (e) =>{
e.preventDefault();
this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}), ()=>{
console.log('newctc', this.state.newCtc)
this.addContact();
});
}
addContact = ()=>{
let newCtcList = [...this.state.ctcList];
newCtcList.push({...this.state.newCtc});
console.log('newctc addcontact', this.state.newCtc);
console.log('newctclist',newCtcList);
this.setState({ ctcList: newCtcList }, ()=>{
console.log(this.state.ctcList);
this.clearInput();
});
};
clearInput = ()=>{
this.setState({test1:'',test2:''});
this.setState(Object.assign(this.state.newCtc,{test1:'', test2:''}));
};
render() {
return (
<div>
<input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>
<form onSubmit = {this.newSubmit}>
<input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}
/>
<input type='text' name={'test2'} value={this.state.test2} onChange = {this.onChangeInput}
/>
<button type='submit'> submit </button>
</form>
</div>
)
}
}
export default ContactList;
Here a problematic line
// newCtc is empty => so Object.assign, simply returns {test1: 'some value', test2: // somevalue }
// this.setState then merges this into the array, so newCtc is not actually updated
// but the properties test1 and test2
this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}));
import React, { Component } from 'react';
import Contact from './Contact';
import TestData from './TestData';
class ContactList extends Component {
constructor(props){
super(props);
this.state = {
name: '',
test1:'',
test2:'',
newCtc:{},
ctcList:[],
arr: []
}
}
async componentDidMount() {
try{
const result = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await result.json()
this.setState({arr:data})
}catch(err){
console.log(err)
}
}
onChangeInput = (e)=>{
const target = e.target;
const name = target.name;
const value = target.value;
console.log(value)
this.setState({
[name]: value
});
}
newSubmit = (e) =>{
e.preventDefault();
const ctcCopy = Object.assign({}, this.state.newCtc);
this.setState({newCtc: Object.assign(ctcCopy, {
test1: this.state.test1,
test2: this.state.test2,
})})
console.log(this.state.newCtc)
this.addContact();
this.clearInput();
console.log(this.state.newCtc);
}
// I would also copy this.state.newCtc
addContact = ()=>{
this.setState({ ctcList:[ ...this.state.ctcList, ...this.state.newCtc] });
console.log(this.state.ctcList);
};
clearInput = ()=>{
this.setState({test1:'',test2:''});
const ctcCopy = Object.assign({}, this.state.newCtc);
this.setState({newCtc: Object.assign(ctcCopy, {
test1: this.state.test1,
test2: this.state.test2,
})})
};
render() {
return (
<div>
<Contact firstName = {this.state.name} lastName='mcdaniel' phoneNumber = '585-721-3824' />
<input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>
<TestData data={this.state.arr} />
<form onSubmit = {this.newSubmit}>
<input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}
/>
<input type='text' name={'test2'} value={this.state.test2} onChange = {this.onChangeInput}
/>
<button type='submit'> submit </button>
</form>
</div>
)
}
}
export default ContactList;
I'm trying to create small app based on Json server package which will help me to remember movies I want to watch when I have free time, want to learn React and Axios so I'm doing it with these technologies , Idea is when I click on add movie button - movie will be added to Json database,
when click on delete - particular movie will be deleted
and when click on the list - I will be able to edit text,
Delete works if I do something like http://localhost:3000/movies/1, to show what id should it delete, but is there any way to set it? To delete the list connected to button I'm clicking at? something like http://localhost:3000/movies/"id"? I will be grateful for any help as I totally don't have any idea how to move on with it
import React from 'react';
import ReactDom from 'react-dom';
import axios from 'axios';
import List from "./list.jsx";
class Form extends React.Component {
constructor(props) {
super(props)
this.state = {
name:'',
type:'',
description:'',
id:'',
movies: [],
}
}
handleChangeOne = e => {
this.setState({
name:e.target.value
})
}
handleChangeTwo = e => {
this.setState({
type:e.target.value
})
}
handleChangeThree = e => {
this.setState({
description:e.target.value
})
}
handleSubmit = e => {
e.preventDefault()
const url = `http://localhost:3000/movies/`;
axios.post(url, {
name: this.state.name,
type: this.state.type,
description:this.state.description,
id:this.state.id
})
.then(res => {
// console.log(res);
// console.log(res.data);
this.setState({
movies:[this.state.name,this.state.type,this.state.description, this.state.id]
})
})
}
handleRemove = (e) => {
const id = this.state.id;
const url = `http://localhost:3000/movies/`;
// const id = document.querySelectorAll("li").props['data-id'];
e.preventDefault();
axios.delete(url + id)
.then(res => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
})
}
// editMovie = e => {
// const url = `http://localhost:3000/movies/`;
// e.preventDefault();
// const id = e.target.data("id");
// axios.put(url + id, {
// name: this.state.name,
// type: this.state.type,
// description:this.state.description,
// })
// .then(res => {
// console.log(res.data);
// })
// .catch((err) => {
// console.log(err);
// })
// }
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" placeholder="movie" onChange={this.handleChangeOne}/>
<input type="text" placeholder="type of movie" onChange={this.handleChangeTwo}/>
<textarea cols={40} rows={5} placeholder="description of the movie" onChange={this.handleChangeThree}></textarea>
<input type="submit" value="Add movie"></input>
<List removeClick={this.handleRemove} editClick={this.editMovie}/>
</form>
)
}
}
export default Form
List:
import React from 'react';
import ReactDom from 'react-dom';
import axios from 'axios';
class List extends React.Component{
constructor(props){
super(props)
this.state = {
movies: [],
}
}
componentDidMount() {
const url = `http://localhost:3000/movies`;
console.log(url);
axios.get(url)
.then(res => {
console.log(res.data);
const movies = res.data;
this.setState({
movies: movies
})
})
.catch((err) => {
console.log(err);
})
}
// editMovie =(e) => {
// console.log("it works with edit!");
// if (typeof this.props.editClick === "function") {
// this.props.editClick(e)
// } else {
// console.log("Doesn't work with edit");
// }
// }
removeMovie =(e) => {
console.log("it works with remove!");
if (typeof this.props.removeClick === "function") {
this.props.removeClick(e)
} else {
console.log("Doesn't work with remove");
}
}
render(){
let movies = this.state.movies.map(e =>
<ul onClick={this.editMovie}>
<li data-id={e.id}>
{e.name}
</li>
<li data-id={e.id}>
{e.type}
</li>
<li data-id={e.id}>
{e.description}
</li>
<button type="submit" onClick={this.removeMovie}>Delete</button>
</ul>)
return(
<div>
{movies}
</div>
)
}
}
export default List;
Json part
{
"movies": [
{
"id": 1,
"name": "Kongi",
"type": "drama",
"description": "movie about monkey"
},
{
"id": 2,
"name": "Silent Hill",
"type": "thriller",
"description": "movie about monsters"
},
{
"name": "Harry potter",
"type": "fantasy",
"description": "movie about magic and glory",
"id": 3
}
]
}
You could pass the movie object to the removeMovie function in your List component and pass that to the this.props.removeClick function. You could then take the id of the movie to use for your request, and remove the movie from state if the DELETE request is successful.
Example
class Form extends React.Component {
handleRemove = movie => {
const url = `http://localhost:3000/movies/${movie.id}`;
axios
.delete(url)
.then(res => {
this.setState(previousState => {
return {
movies: previousState.movies.filter(m => m.id !== movie.id)
};
});
})
.catch(err => {
console.log(err);
});
};
// ...
}
class List extends React.Component {
removeMovie = (e, movie) => {
e.preventDefault();
if (this.props.removeClick) {
this.props.removeClick(movie);
}
};
// ...
render() {
return (
<div>
{this.state.movies.map(movie => (
<ul onClick={this.editMovie}>
<li data-id={movie.id}>{movie.name}</li>
<li data-id={movie.id}>{movie.type}</li>
<li data-id={movie.id}>{movie.description}</li>
<button type="submit" onClick={e => this.removeMovie(e, movie)}>
Delete
</button>
</ul>
))}
</div>
);
}
}
An simple example using hooks:
const URL = 'https://jsonplaceholder.typicode.com/users'
const Table = () => {
const [employees, setEmployees] = React.useState([])
React.useEffect(() => {
getData()
}, [])
const getData = async () => {
const response = await axios.get(URL)
setEmployees(response.data)
}
const removeData = (id) => {
axios.delete(`${URL}/${id}`).then(res => {
const del = employees.filter(employee => id !== employee.id)
setEmployees(del)
})
}
const renderHeader = () => {
let headerElement = ['id', 'name', 'email', 'phone', 'operation']
return headerElement.map((key, index) => {
return <th key={index}>{key.toUpperCase()}</th>
})
}
const renderBody = () => {
return employees && employees.map(({ id, name, email, phone }) => {
return (
<tr key={id}>
<td>{id}</td>
<td>{name}</td>
<td>{email}</td>
<td>{phone}</td>
<td className='opration'>
<button className='button' onClick={() => removeData(id)}>Delete</button>
</td>
</tr>
)
})
}
return (
<>
<h1 id='title'>React Table</h1>
<table id='employee'>
<thead>
<tr>{renderHeader()}</tr>
</thead>
<tbody>
{renderBody()}
</tbody>
</table>
</>
)
}
ReactDOM.render(<Table />, document.getElementById('root'));