How to pass partial data to a parent component in react - reactjs

I have the following Component TBorrowed
import React, { Fragment, useState} from "react";
import {Link} from 'react-router-dom';
const EditItem = ({ item }) => {
const [name, setName] = useState(item.name)
const saveData = async (e) => {
e.preventDefault();
const body = { name}
await fetch(`http://127.0.0.1:5000/item/edit/${item.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
})
}
return (
<Fragment>
<Link className="link" data-toggle="modal" data-target={`#id${item.id}`} >{item.name}</Link>
<div className="modal" id={`id${item.id}`}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">Edit Item</h4>
</div>
<div className="modal-body">
<label>Name</label>
<input value={name} onChange={e => { setName(e.target.value) }} type="text" />
</div>
<div className="modal-footer">
<button onClick={e => { saveData(e) }} type="button" className="btn btn-outline-success ml-auto" data-dismiss="modal">Save</button>
</div>
</div>
</div>
</div>
</Fragment>
)
}
export default EditItem;
The above is called in another component, Main as shown below
import React, { useState} from 'react';
import TBorrowed from './TBorrowed';
const Main = () => {
const [items, setItems] = useState([]);
...MANY ITEMS SKIPPED...
return (
<table className="layout">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Code</th>
</tr>
</thead>
<tbody>
{
items.map((item, index) => (
<tr key={item.id}>
<td>{index + 1}</td>
<td>{item.name}</td>
<td>{<TBorrowed item={item} />}</td>
</tr>
))
}
</tbody>
</table>
)
}
export default Main;
The above works well where I am able to see the item code in the Main component's <td></td> when rendered, which when I click, I am able to edit the particular item in a modal.
My issue is I no longer want to edit an item in a modal but I want it rendered on it's own page for editing.
When I try it without a data-toggle = "modal" in the TBorrowed component, I get all the contents of the TBorrowed component displaying in the Main component where the modal is called i.e <td>{<TBorrowed item={item} />}</td>. All the data in TBorrowed is shown in that <td></td> instead of just the item.code as it was showing while using the modal
My code has some parts missing so it can fit here.
Please assist, and if there's more information required I'll provide it.

Related

How can i change this code to react redux

Here i want to change this code to react redux. How i can change this code using react redux. Kindly provide any solutions for changing this code to react redux using GET method api. As iam new to react js how can i change this code using react redux.
import React from "react";
import { useState, useEffect } from "react";
import { Link } from "react-router-dom";
export default function User() {
const [users, setUsers] = useState([]);
const f = async () => {
const res = await fetch("https://reqres.in/api/userspage=1");
const json = await res.json();
setUsers(json.data);
};
useEffect(() => {
f();
}, []);
const handleLogout = (e) => {
localStorage.clear();
window.location.pathname = "/";
}
return (
<div>
<h1>List Users</h1>
<div>
<button onClick={handleLogout}>Logout</button>
<nav>
<Link to="/Home">Home</Link>
</nav>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>First_name</th>
<th>Last_name</th>
<th>Email</th>
<th>Avatar</th>
</tr>
</thead>
<tbody>
{users.length &&
users.map((user) => {
return (
<tr>
<td> {user.id}</td>
<td>{user.first_name}</td>
<td> {user.last_name} </td>
<td>{user.email}</td>
<td> <img key={user.avatar} src={user.avatar} alt="avatar" /></td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
}

How to create multiple layouts in Next js?

I want to create another layout on my nextjs app. I saw this method somewhere, on adding multiple/nested layout in next js. The problem is I can't make this work, there's always this error:
Error: MyApp(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
Now this is my code:
My _app.js
import Layout from "./../components/Layout";
function MyApp({ Component, pageProps }) {
const getLayout = Component.pageLayout || ((page) => <Layout>{page}</Layout>);
return getLayout(<Component {...pageProps} />);
}
export default MyApp;
This is my Layout
import React, { Fragment, useState, useEffect, useRef } from "react";
import { useRouter } from 'next/router';
import NavBar from "./../NavBar";
import MidNavBar from "./../MidNavBar";
import Banner from "./../Banner";
const Layout = ({ children, navBarRefProps }) => {
const navBarRef = useRef();
const router = useRouter();
const navBarRefPropsHandle = (props) => {
navBarRef.current = props.current;
navBarRefProps(navBarRef.current);
}
return(
<Fragment>
<div className="wrapper">
<NavBar navBarRefProps={ navBarRefPropsHandle } />
<div className="inner_wrapper">
<Banner/>
{
router.pathname !== "/" ?
<MidNavBar midNavBarRefProps = {midNavBarRefPropsHandle} dummyRefProps={dummyRefPropsHandle}/>
:
""
}
{ children }
</div>
</div>
</Fragment>
)
}
This is my AnotherLayout
const AnotherLayout = ({ children }) => {
return(
<Fragment>
<main>
<div>
<aside className="menu">
<div className="menu_header">
<div className="menu_title">
<span>
Panel
</span>
<button onClick={logoutHandle}>
logout
</button>
</div>
<button className="burger" onClick={openMenuHandle}>
<div className="burger-one">
</div>
<div className="burger-two">
</div>
<div className="burger-three">
</div>
</button>
</div>
<div ref={menuBodyRef} className="menu_body">
<ul>
<li>
<Link href={ url + "/rooms" }>
<div>
</div>
News
</Link>
</li>
<li>
<Link href={ url + "/events" }>
<div>
</div>
Events
</Link>
</li>
<li>
<Link href={ url + "/categories" }>
<div>
<i className="fas fa-snowboarding"></i>
</div>
Activities
</Link>
</li>
</ul>
</div>
</aside>
<section className="container_panel">
{ children }
</section>
</div>
</main>
</Fragment>
)
}
export default AnotherLayout;
And this is my index page
import React, { Fragment, useState, useEffect, useRef } from "react";
import AnotherLayout from "./../../../../components/AnotherLayout";
const Panel = () => {
// a lot of codes here.....
return(
<Fragment>
<section>
<div>
<div>
<h1><span>Rooms</span> Panel</h1>
</div>
<div className="container_table">
<table>
<thead>
<tr>
<td>Rooms</td>
<td>
<div>
<input type="search" name="search" placeholder="search"/>
</div>
</td>
<td className="col_add">
<button>
add
rooms
</button>
</td>
</tr>
</thead>
<tbody>
{
rooms.map(room => {
return(
<tr key={room._id}>
<td colSpan="2">
<button>{room.title}</button>
</td>
<td className="ud">
<button className="edit">
edit
</button>
<button className="delete">
delete
</button>
</td>
</tr>
)
})
}
</tbody>
<tfoot>
<tr>
<td>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</section>
</Fragment>
)
}
Panel.getLayout = (page) => {
<AdminLayout>
{ page }
</AdminLayout>
}
export default Panel;
Thank you!.
Solved this by adding return()
Panel.getLayout = (page) => {
return(
<AdminLayout>
{ page }
</AdminLayout>
)
}

Modify the state with other component for the input in React

I carry out a project which can modify the price of a product (recovered from a fake API) and then at the click of a button carries out the update by calculating the VAT of 20%. I encounter a problem I would like to have a price state and that in this state it's the value of my input namely {listProduct.price} but it doesn't work.
If you have solutions, I am interested, thank you in advance. (sorry I'm new to React I still have a bit of trouble with all these concepts)
import React, { Component } from 'react'
import '../css/ProductsDetails.css'
import {AiOutlineArrowLeft} from "react-icons/ai";
import {Link} from 'react-router-dom'
export default class ProductsDetails extends Component {
state = {
id: this.props.match.params.id,
price:
}
updatePrice = (e) => {
console.log(e);
this.setState({
price: e.target.value
})
}
render() {
const {location: {state: {listProduct}}} = this.props;
return (
<div className="products__details">
<Link to="/"><AiOutlineArrowLeft className="nav__arrow" /></Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img className="product__img" src={listProduct.image} alt="Affichage du produit"/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price">
<input className="input__price" type="text" value={listProduct.price} onChange={this.updatePrice} />
<p>Price (including VAT): {Math.round((listProduct.price + listProduct.price * 0.2)*100) /100} €</p>
<br/>
<input className="btn__update" type="submit" value="Update product" />
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className="product__category">{listProduct.category}</p>
</div>
</div>
</div>
)
}
}
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {productsData: []};
}
componentDidMount = () => {
axios.get('https://fakestoreapi.com/products?limit=7')
.then(res => {
console.log(res.data)
this.setState ({
productsData: res.data
})
})
}
render() {
const listsProducts = this.state.productsData.map(listProduct => {
return <tbody className="products__body">
<tr>
<td> <Link to={{pathname: "/products-details/" + listProduct.id,state: {listProduct}}}>{listProduct.title}</Link></td>
<td className="products__category">{listProduct.category}</td>
<td>{listProduct.price}</td>
<td>{Math.round((listProduct.price + listProduct.price * 0.2)*100) /100}</td>
</tr>
</tbody>
})
return (
<main className="products">
<h1 className="products__title">Products management</h1>
<table cellSpacing="0">
<thead className="products__head">
<tr>
<th className="table--title">Product name</th>
<th className="table--title">Category</th>
<th className="table--title">Price</th>
<th className="table--title">Price (including VAT)</th>
</tr>
</thead>
{listsProducts}
</table>
</main>
)
}
}
Inside a react component:
1 - You declare the initial state of your component, which is, in this case, the price that the product has before the user writes something. For now, we'll set it to 0:
state = {
id: this.props.match.params.id,
price: this.props.listProduct.price ? this.props.listProduct.price : 0
}
2 - Then, in the render method, we access the price value from this.state
3 - Finally, we modify our input element so that it gets the value of the price.
<input className="input__price" type="text" value={price} onChange={this.updatePrice} />
The rest of the component was working well.
This is the result:
import React, { Component } from 'react'
import '../css/ProductsDetails.css'
import {AiOutlineArrowLeft} from "react-icons/ai";
import {Link} from 'react-router-dom'
export default class ProductsDetails extends Component {
state = {
id: this.props.match.params.id,
price: '0'
}
updatePrice = (e) => {
console.log(e);
this.setState({
price: e.target.value
})
}
render() {
const {price} = this.state
return (
<div className="products__details">
<Link to="/"><AiOutlineArrowLeft className="nav__arrow" /></Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img className="product__img" src={listProduct.image} alt="Affichage du produit"/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price">
<input className="input__price" type="text" value={price} onChange={this.updatePrice} />
<p>Price (including VAT): {Math.round((listProduct.price + listProduct.price * 0.2)*100) /100} €</p>
<br/>
<input className="btn__update" type="submit" value="Update product" />
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className="product__category">{listProduct.category}</p>
</div>
</div>
</div>
)
}
}
Start off with the price at 0 (not in quotes) in state, and then...
const price = this.state.price || (this.props.listProduct ? this.props.listProduct.price : 0)
<input className="input__price" type="text" value={price} onChange{this.updatePrice} />
So if the state value has been updated, that will be used, if not it will check if the price is available in props and use that, and if not it will display zero.

how to react-js-pagination implement with react hook data table

How to integrate pagination code with hooks method data table with. im using react-js-pagination nmp package but there is no one explanation for implement with hook method program.
This my data table code:
import React, { useEffect, useState } from 'react';
import axios from 'axios'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Link} from 'react-router-dom';
const ProTable = () => {
const [data, setData] = useState([]);
useEffect(() => {
loadData();
}, []);
const loadData = async() => {
axios.get('http://localhost:5000/api/clientgetdata')
.then(response => {
setData(response.data.map);
}
const delPro = (item,e) => {
var option = window.confirm(`Are you sure to delete ${e.clientName} OF ${item.projectName}`)
if(option){
const check = axios.delete(`http://localhost:5000/api/clientdelpro/${e.clientName}/${item.projectName}`).then(res => {
//console.log(clientname)
window.location.reload(false)
})
}
}
return (
<>
<div className="row addButton">
<div className="col-lg-1">
<Link
className="btn btn-outline-primary mr-2"
to={'/client/addpro'}
>New</Link>
</div>
<div className="col-lg-1">
{/* <button variant="primary" >Delete</button> */}
</div>
</div>
<div className="row hrtable">
<div className="col-lg-10 col-sm-6 col-md-6">
<div className="table-responsive tcenter" >
<table className="table table-bordered table-hover table-sm">
<thead className="thead-dark">
<tr>
<th scope="col"><input type="checkbox" /></th>
<th scope="col">Client Name</th>
<th scope="col">Project Name</th>
<th scope="col">Status</th>
<th>Action</th>
</tr>
</thead>
{ (data.length > 0) ? data.map( e => {
return (
<>
{e.project.map(item=> {
return (
<tbody>
<tr>
<th scope="row">
<input type="checkbox"/>
</th>
<td><ul>{e.clientName}</ul></td>
<td><ul>{item.projectName}</ul></td>
<td><ul>{item.proStatus}</ul></td>
<td>
<Link
className="btn btn-outline-primary mr-2"
to={`/project/edit/${e.clientName}/${item.projectName}`} >
Edit
</Link>
<button
className="btn btn-danger"
onClick={() => delPro(item,e)}>
Delete
</button>
</td>
</tr>
</tbody>
);
})}
</>
);
}) : <tr><td colSpan="5">No Records Found</td></tr> }
</table>
</div>
</div>
</div>
</>
);
}
export default ProTable;
This is Reaci-js-pagination code.
I am trying to follow this tutorial to create a pagination in my application https://www.npmjs.com/package/react-js-pagination#usage
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Pagination from "react-js-pagination";
require("bootstrap/less/bootstrap.less");
class App extends Component {
constructor(props) {
super(props);
this.state = {
activePage: 15
};
}
handlePageChange(pageNumber) {
console.log(`active page is ${pageNumber}`);
this.setState({activePage: pageNumber});
}
render() {
return (
<div>
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={10}
totalItemsCount={450}
pageRangeDisplayed={5}
onChange={this.handlePageChange.bind(this)}
/>
</div>
);
}
}
plz help me how integrate both code
Try by converting it into hooks
const [state, setState] = React.useState({activePage: 15});
const handlePageChange=(pageNumber) => {
setState({activePage: pageNumber});
// make api call for next page
}
return (
<div>
<Pagination
activePage={state.activePage}
itemsCountPerPage={10} // pass your fixed item per pages
totalItemsCount={450} // total item -> per-page * no of page
pageRangeDisplayed={5}
onChange={handlePageChange}
/>
</div>
);

CoreUI Make API Calls

I have created some basic beginner React apps. But now I want to try using a template "core-ui".
https://github.com/coreui/coreui-free-react-admin-template
I would like to make requests to some external endpoints and retrieve some data but I'm not sure where to do it.
Here's what I've done on my own:
import React from 'react';
import RowCreator from './RowCreator';
class DisplayCountries extends React.Component {
constructor(props){
super(props);
this.state = {countries:[],
countriesClone:[]
};
}
componentDidMount() {
const axios = require('axios');
const url = 'http://localhost:8080/demo/api/countries';
axios.get(url).then(res=>{
console.log(res.data);
this.setState({countries:res.data,
countriesClone:res.data});
}).catch(error=>{
console.error('Error', error);
})
}
handleOnChange(event){
var filteredString = event.target.value;
var filteredCountries = [];
for(var country of this.state.countries){
if(country.cioc.toLowerCase().indexOf(filteredString.toLowerCase())>=0 ||
country.name.toLowerCase().indexOf(filteredString.toLowerCase())>=0 ||
country.capital.toLowerCase().indexOf(filteredString.toLowerCase())>=0 ||
country.region.toLowerCase().indexOf(filteredString.toLowerCase())>=0 ||
country.subregion.toLowerCase().indexOf(filteredString.toLowerCase())>=0 ){
filteredCountries.push(country);
}
}
this.setState({countriesClone:filteredCountries});
}
render(){
return (<div>
<div className="headerBox">
<div className="row">
<div className="col-sm-12 text-center">
<h1>Search Countries</h1>
</div>
</div>
<div className="row">
<div className="col-sm-12 text-center">
<h3>Demo to filter the list of countries</h3><br/>
</div>
</div>
</div>
<div className="searchBox">
<div className="row text-right">
<div className="col-sm-3"/>
<div className="col-sm-6 text-center">
<br/><input type="text" className="form-control input-lg" placeholder="Search any field by name" onChange={this.handleOnChange.bind(this)}/><br/>
</div>
<div className="col-sm-3"/>
</div>
</div>
<div className="container">
<div className="row">
<div className="col-sm-12"><br/>
<table className="table table-striped table-bordered">
<thead>
<tr>
<th>CIOC</th>
<th>Country</th>
<th>Capital</th>
<th>Region</th>
<th>Sub Region</th>
</tr>
</thead>
<tbody>
{this.state.countriesClone.map(country => <RowCreator item={country} key={country.cioc}/>)}
</tbody>
</table>
</div>
</div>
</div>
</div>
)}
}
export default DisplayCountries;
But when I review the view of the CoreUI page, I can't figure out where to add my constructor, etc. Any ideas
Here's an example of a .js file for one of the pages:
import React, { useState, useEffect } from 'react'
import { useHistory, useLocation } from 'react-router-dom'
import {
CBadge,
CCard,
CCardBody,
CCardHeader,
CCol,
CDataTable,
CRow,
CPagination
} from '#coreui/react'
import processesData from './ProcessData'
const getBadge = status => {
switch (status) {
case 'Active': return 'success'
case 'Inactive': return 'secondary'
case 'Pending': return 'warning'
case 'Banned': return 'danger'
default: return 'primary'
}
}
const Processes = () => {
const history = useHistory()
const queryPage = useLocation().search.match(/page=([0-9]+)/, '')
const currentPage = Number(queryPage && queryPage[1] ? queryPage[1] : 1)
const [page, setPage] = useState(currentPage)
const pageChange = newPage => {
currentPage !== newPage && history.push(`/processes?page=${newPage}`)
}
useEffect(() => {
currentPage !== page && setPage(currentPage)
}, [currentPage, page])
return (
<CRow>
<CCol xl={12}>
<CCard>
<CCardHeader>
<h4 id="process" className="card-title mb-0">Processes</h4>
</CCardHeader>
<CCardBody>
<CDataTable
items={processesData}
fields={[
{ key: 'id', _classes: 'font-weight-bold' },
'name', 'startDate', 'endDate'
]}
columnFilter
tableFilter
hover
sorter
striped
itemsPerPageSelect
itemsPerPage={5}
activePage={page}
clickableRows
onRowClick={(item) => history.push(`/process/${item.id}`)}
/>
</CCardBody>
</CCard>
</CCol>
</CRow>
)
}
export default Processes
I think you're getting confused because in core-ui page, a functional component is written which uses hooks. To read more about hooks, Please go through the official docs if you've not. https://reactjs.org/docs/hooks-intro.html
useState
useEffect
You can convert your class component into a functional component like this
const DisplayCountries = () => {
[countries, setCountries] = useState([]);
useEffect(() => {
const axios = require("axios");
const url = "http://localhost:8080/demo/api/countries";
axios
.get(url)
.then((res) => {
setCountries(res.data);
})
.catch((error) => {
console.error("Error", error);
});
}, []); // Empty array of dependency makes it equivalent to componentDidMount
return (<div/>) // render your element like you'd do in a class component
};

Resources