Adding to component from another component using React - javascript

I have a footer that I created in App.js and now I have another component called KokPlayer.js and I want to add buttons from KokPlayer.js to the footer in App.js.
How can I do that?
App.js
render() {
const { expanded } = this.state;
return (
<React.Fragment>
<nav
className="footer navbar navbar-light bg-success mb-auto"
ref="footerRef"
/>
</React.Fragment>
);
}
KokPlayer.js
render() {
// Add this block to footer
return (
<div
style={{ display: "block", margin: "0 auto", verticalAlign: "middle" }}
>
<Button onClick={this.play} className="mr-3">
play()
</Button>
<Button onClick={this.pause} className="mr-3">
pause()
</Button>
<Button onClick={this.toggleFullScreen} className="mr-3">
FullScreen()
</Button>
</div>
);
}

As I understand what you wrote in the comments, you can pass a prop to KokPlayer component then you can hide the elements that you don't want to show them up in App.js
in App.js
import KokPlayer from './KokPlayer' // KokPlayer location
....
render() {
const { expanded } = this.state;
return (
<React.Fragment>
<nav
className="footer navbar navbar-light bg-success mb-auto"
ref="footerRef"
/>
<KokPlayer showButtonsOnly={true} /> // the buttons here
</React.Fragment>
);
}
KokPlayer.js
render() {
// Add this block to footer
return (
<div>
{!this.props.showButtonsOnly && <div> // it wouldn't be shown in App.js
Screen Here
</div>}
<div style={{ display: "block", margin: "0 auto", verticalAlign: "middle" }}
>
<Button onClick={this.play} className="mr-3">
play()
</Button>
<Button onClick={this.pause} className="mr-3">
pause()
</Button>
<Button onClick={this.toggleFullScreen} className="mr-3">
FullScreen()
</Button>
</div>
</div>
);
}

Related

React Value is undefined on Button Click [used for passing state up]

Child Class Below
class Navbar extends Component {
constructor(props) {
super(props);
this.handlePageChange = this.handlePageChange.bind(this);
}
handlePageChange(e) {
this.props.handlePageChange(e.target.value);
console.log(e.target.value); <----- This is undefined
}
render() {
return (
<div className="navbar">
<div className="branding">
<img src=#### alt="####### logo"></img>
<h2>#######</h2>
<span>Web Portal</span>
</div>
<div className="navlinks">
<span>MENU</span>
<div className="nav-boxes">
<button onClick={this.handlePageChange} value="Overview">
<HomeIcon style={{ fill: "#5c66bd" }} />
<span>Overview</span>
</button>
</div>
<div className="nav-boxes">
<button onClick={this.handlePageChange} value="Knowledge">
<SchoolIcon style={{ fill: "#4d7d48" }} />
<span>Knowledge Base</span>
</button>
</div>
<div className="nav-boxes">
<button onClick={this.handlePageChange} value="Health">
<FavoriteIcon style={{ fill: "#63182a" }} />
<span>Health</span>
</button>
</div>
<div className="nav-boxes">
<button onClick={this.handlePageChange} value="Support">
<ContactSupportIcon style={{ fill: "#5c66bd" }} />
<span>Live Support</span>
</button>
</div>
<div className="nav-boxes">
<button onClick={this.handlePageChange} value="Documents">
<ArticleIcon style={{ fill: "#8a7f1c" }} />
<span>Documents</span>
</button>
</div>
</div>
<NavLogin />
</div>
);
}
}
export default Navbar;
This is my Navigation, i want the "current page" to be changed, passing the state
upward, where it can then be passed down to the content to show the correct page.
I've added a console.log for the HandlePageChange function and see that my e.target.value
is undefined. I cant see why as its being called when i click on the Nav buttons
Parent Class if needed and its something obvious
class App extends Component {
constructor(props) {
super(props);
this.handlePageChange = this.handlePageChange.bind(this);
this.state = { currpage: "Overview" };
}
handlePageChange(newPage) {
this.setState({ currpage: newPage });
}
render() {
const { currpage } = this.state;
return (
<div className="dashboard">
<Navbar handlePageChange={this.handlePageChange} currpage={currpage} />
<Content
handlePageChange={this.handlePageChange}
username={"#####"}
currpage={currpage}
/>
</div>
);
}
}
I just cant see why my e.target.value is undefined
e.target is the most nested element on anywhere that you have clicked. since you have nested an span inside the button, in the callback e.target is actually the span, which doesn't have a value.
Use e.currentTarget instead, which contains value. the currentTarget property on an event refers to the element with the event handler (Button).
handlePageChange(e) {
this.props.handlePageChange(e.currentTarget.value);
console.log(e.currentTarget.value);
}

Load a react component on button onClick

I have the following code for a button in my ReactApp to open a new window with specific size:
<button
type="button"
style={{ height: '20px', width: '50px' }}
className="btn btn-primary"
onClick={() => {
window.open(
"",
"Popup",
"width=975, height=92, top=30"
);
}}
/>
I want to load another component when user clicks on the button. How can I achieve that? I have tried to load the component and then use it like the following, but didn't work:
import component from "./component"
<button
type="button"
style={{ height: '20px', width: '50px' }}
className="btn btn-primary"
onClick={() => {
window.open(
"{<component />}",
"Popup",
"width=975, height=92, top=30"
);
}}
/>
What would be the best way to do this?
Here is my component:
export default function component(props) {
return (
<div className="container">
<div className="cabinet"><img src={image} />
<div className="devices"> <img src={image2} />
</div>
</div>
);
}
Add a state in main page and pass it to component
const [open, setOpen] = useState[false];
const onClickHandle = () => {
setOpen(true);
};
return (
<>
<button
type="button"
style={{ height: '20px', width: '50px' }}
className="btn btn-primary"
onClick={onClickHandle}
/>
<component open={open} />
</>
);
Add a new props to control the component
export default function component(props) {
const { open } = props;
return (
<>
{open && (
<div className="container">
<div className="cabinet">
<img src={image} />
<div className="devices">
{' '}
<img src={image2} />
</div>
</div>
</div>
)}
</>
);
}
Using state hooks and conditional rendering, you can load a react component on a button onClick.
const [visible, setVisible] = React.useState(false);
function click(e) {
e.preventDefault();
setVisible(true);
}
return (
<div>
<button onClick={(event) => {
click(event)
}} />
{isVisible && (
<YourComponent />
)
}
</div>
)

How can i use useParams() with an onClick button to navigate to different pages and display the data in react.js?

I'm working on a billing app. I have managed to fetch the Products from an API..... But now I'm trying to use useParams() to navigate to random pages that would display the items according to the ID by pressing a button...the navigation works fine but it wont display the data of that passed ID, it displays all the data in my API.
I would really appreciate some help or feedback, Thanks !
Item.js:
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getItems } from "../store/actions/itemsActions";
import { Link } from "react-router-dom";
import "./Items.css";
function Items({ getItems, items }) {
useEffect(() => {
getItems();
}, []);
function getRandomElFromArray(items) {
return Math.floor(Math.random() * items);
}
return (
<div>
<div className="container">
<div
className="image"
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: 200,
width: 100,
}}
>
<img src="http://i.stack.imgur.com/yZlqh.png" alt="" />
</div>
</div>
<div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div className="item-preview">
{items &&
items.items &&
items.items.map((item) => (
<div key={item.id}>
<h4>
ID:<Link to={`/bills/${item.id}`}> {item.id}
<button className="button4">Analyse Receipt</button>
</Link>
</h4>
</div>
))}
</div>
</div>
</div>
</div>
);
}
const mapStateToProps = (state) => {
return {
items: state.items,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getItems: () => dispatch(getItems()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Items);
Billing.js:
import React, { useState } from "react";
import "./Bill.css";
import { Link, useParams, Switch, Route } from "react-router-dom";
import { connect } from "react-redux";
import { getItems } from "../store/actions/itemsActions";
function BillList({ items }) {
const [counter, setCounter] = useState(1);
const { id } = useParams();
function Display(props) {
return <label style={{ marginLeft: ".5rem" }}>{props.message}</label>;
}
return (
<div className="bills">
<div className="explore-container">
{items &&
items.items &&
items.items.filter((item) => item.id === id)
.map((item) => (
<div className="item-list" key={item.id}>
<h2>Title: {item.title}</h2>
<h4>price: {item.price}</h4>
</div>
))}
</div>
<div
className="main-title"
style={{
textAlign: "center",
justifyContent: "center",
alignItems: "center",
fontSize: 14,
}}
>
<h1>Bakery</h1>
<h1>Company Gbr</h1>
<h1>Oranienburger Straße 120</h1>
<h1>10119 Berlin</h1>
</div>
<div className="bills-container">
<div></div>
{/* pass in the details */}
<div className="item-list">
{items &&
items.items &&
items.items.map((item) => (
<React.Fragment key={item.id}>
<div className="bill-time">
<div className="bill">
<h4>
{" "}
<strong>Bill: </strong>
{item.billNumber}
</h4>
</div>
<div className="time">
<h4>
{" "}
<strong>Time: </strong>
{item.created_datetime}
</h4>
</div>
</div>
----------------------------------
----------------------------------
---------------------------------- --------------------
{/* Counter */}
<div className="price-total">
<div className="title">
<h3>
{" "}
<strong>Title: </strong>
{item.title}
</h3>
<div className="counter">
<strong>
<Display message={counter} />x
</strong>
</div>
</div>
<div className="increase">
<button onClick={() => setCounter(counter + 1)}>+</button>
</div>
<div className="decrease">
<button onClick={() => setCounter(counter - 1)}>-</button>
</div>
{/* Price and total */}
<div className="price">
<h4>
<strong>Price: {parseFloat(item.price)}€</strong>
</h4>
</div>
<div className="total">
<h4>Total: {parseFloat(item.price * counter)}€</h4>
</div>
</div>
</React.Fragment>
))}
</div>
{/* <div>
<h4>
Table: Counter
Terminal:
Ust-Id: DE11111111</h4>
</div> */}
</div>
<div className="button-path">
<Link to="/items">
<div className="button">
<button className="main-button">Analyse Receipt</button>
</div>
</Link>
</div>
<Switch>
<Route path="/bills/:id" />
</Switch>
</div>
);
}
const mapStateToProps = (state) => {
return {
items: state.items,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getItems: () => dispatch(getItems()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(BillList);
The ":" of path="/bills/:id" is only used to designate id as a route parameter, it isn't meant to be part of any URL. When you link to to={`/bills/:${items.id}`} you are adding ":" to the id string value.
Remove it from the link. You should also ensure that the Items component has items to map, where each specific item mapped renders the link/button to link to the appropriate bill list page.
<Link to={`/bills/${item.id}`}>
<button className="button4">Analyse Receipt</button>
</Link>
The Items route also doesn't specify any route params, so there will be be none in the `Items component.
<Route exact path="/" component={Items} />

Why am I getting warning for functions as a React Child on this

what am I missing? I cant spot it and my grids are not rendering properly. I am getting warnings about functions not valid as a React Child.
render() {
return (
<ModalDynamic
defaultWidth={1200}
defaultHeight={400}
defaultX={100}
defaultY={100}
display={this.props.showPartsModal}
title={
"Parts for Invoice: " +
(this.props.selectedHistory[0] !== undefined
? this.props.selectedHistory[0].invoice_number
: "N/A")
}
dealerPath="[ 12345 ] Some Dealer"
dismissAction={this.props.dismissAction}
>
<div
//className="ag-theme-bootstrap container-fluid full-height zero-gap modal-container"
className="ag-fresh container-fluid full-height zero-gap modal-container"
style={{
height: "calc(100%)",
overflowX: "auto"
}}
id="viewPartsGrid"
>
<AgGridReact
columnDefs={this.state.columns}
rowData={this.props.selectedHistory}
suppressMenuHide="true"
suppressRowClickSelection="false"
suppressColumnVirtualisation="false"
sideBar="false"
rowSelection="single"
enableColResize="true"
enableSorting="true"
enableFilter="true"
onGridReady={this.onGridReady}
/>
</div>
<div className="rnd-footer">
<div className="rnd-left">{this.dealerLabel}</div>
<div className="rnd-right">
{this.state.gridAPI ? (
<OverlayTrigger overlay={this.csvTip}>
<Button
className="btn btn-primary btn-sm"
onClick={() =>
this.state.gridAPI.exportDataAsCsv({
fileName:
"Parts Invoice #" +
(this.props.selectedHistory[0].invoice_number
? this.props.selectedHistory[0].invoice_number
: "N/A")
})
}
>
<i className="fa fa-file-excel-o" />
</Button>
</OverlayTrigger>
) : null}
</div>
</div>
</ModalDynamic>
);
}
}
The code compiles but the grid seems to not do what I am trying to write it to do. Columns are not resizable and the window itself isn't either.
I think this line may give you warning
<div className="rnd-left">{this.dealerLabel}</div>
If this is a function that return some static value. Declare that in a new variable
Example
in render
const Button = <button onClick={this.yourmethod}>Click Me</button>
return (
<Button>
)

Re-render the same component with different parameter

I am working on a react project with similar functionality to a social media site. I have a user profile component below that has links to other user profiles(towards bottom of code below) that are being followed by the current user. Essentially what I am trying to do is re-render the same component with a different user. However, the link to the new user profile doesn't result in the getProfile action getting called so the redux state doesn't update. How can I navigate to the new profile and have the useEffect hook get called again with the new username?
Thank You!
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import GalleryItem from "../gallery-item/gallery-item.component";
import {
getProfile,
addFollow,
removeFollow
} from "../../redux/profile/profile.actions";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faSpinner, faUserEdit } from "#fortawesome/free-solid-svg-icons";
const Profile = ({
getProfile,
addFollow,
removeFollow,
auth,
profile: { userProfile, loading },
props
}) => {
const userAlias = props.match.params.alias;
useEffect(() => {
getProfile(userAlias);
}, [getProfile]);
return loading ? (
<div class="d-flex justify-content-center">
<FontAwesomeIcon
icon={faSpinner}
className="fa-spin"
style={{ height: "50px", width: "50px", color: "white" }}
/>
</div>
) : (
<div className="container ">
<div className="row">
<div className="col-md-12 align-self-center">
<img
className="rounded-circle float-left shadow-lg"
alt="100x100"
src={userProfile.userProfileImage}
data-holder-rendered="true"
style={{ height: "200px", width: "200px" }}
/>
<div
className="vertical-center"
style={{ marginLeft: "260px", marginTop: "50px" }}
>
<h2>
{auth.user === null || auth.user.alias !== userAlias ? (
<b style={{ color: "white" }}>{userAlias}</b>
) : auth.user.alias === userAlias ? (
<b style={{ color: "white" }}>
{userAlias}
<Link className="" to="/profile/edit">
<FontAwesomeIcon
icon={faUserEdit}
className="fontAwesome"
style={{ paddingLeft: "10px", color: "limegreen" }}
/>
</Link>
</b>
) : (
<b>{userAlias}</b>
)}
</h2>
<p>
<b style={{ color: "white" }}>
{" "}
{userProfile.posts.length} Posts
</b>
<b style={{ color: "white" }}>
{" "}
{userProfile.followers.length} Followers{" "}
</b>
<b style={{ color: "white" }}>
{" "}
{userProfile.following.length} Following{" "}
</b>
</p>
{auth.user === null || auth.user.alias === userAlias ? null : auth
.user.alias !== userAlias &&
userProfile.followers.some(
e => e.userAlias === auth.user.alias
) ? (
<button
type="button"
className="btn btn-primary btn-lg "
onClick={e => removeFollow(userProfile.userId)}
>
Following
</button>
) : auth.user.alias !== userAlias ? (
<button
type="button"
className="btn btn-primary btn-lg "
onClick={e => addFollow(userProfile.userId)}
>
Not Following
</button>
) : (
<button
type="button"
className="btn btn-primary btn-lg "
disabled
>
Follow/Unfollow
</button>
)}
</div>
</div>
</div>
<hr />
<div className="row d-flex justify-content-center">
{userProfile.posts.map((post, i) => (
<GalleryItem key={i} post={post} />
))}
</div>
{userProfile.following.length > 0 ? (
<div>
<h1 className="text-white text-center mt-5">Following</h1>
<hr />
**<div className="row justify-content-center text-center px-auto">
{userProfile.following.map((profile, i) => (
<Link className="" to={`/profile/${profile.userAlias}`}>
<img
className="rounded-circle border border-info m-4"
alt="100x100"
src={profile.getFollowingUserProfileImageUrl}
data-holder-rendered="true"
style={{ height: "80px", width: "80px" }}
/>
<div
className="vertical-center"
style={{ marginBottom: "20px", color: "black" }}
>
<h5>{profile.userAlias}</h5>
</div>
</Link>
))}
</div>**
</div>
) :(<div></div>)}
</div>
);
};
Profile.propTypes = {
getProfile: PropTypes.func.isRequired,
profile: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
props: PropTypes.object.isRequired
};
const mapStateToProps = (state, ownProps) => ({
auth: state.auth,
profile: state.profile,
props: ownProps
});
export default connect(
mapStateToProps,
{ getProfile, addFollow, removeFollow }
)(Profile);
You need to track userAlias in the useEffect's dependencies list, the api callback will be called each time it changes.
const userAlias = props.match.params.alias;
useEffect(() => {
getProfile(userAlias);
}, [getProfile, userAlias]);

Categories

Resources