How to display different components when clicking a button on one page? - javascript

I am trying to display different Components when I click a button with my OnClick in the Render Function of my App.js.
I would like to show a certain component when the button is clicked and it hides the other components.
this is an example of what I want to do
return (
<div className={styles.container}>
<img className={styles.image} src={image} alt="COVID-19" />
//If the Country Button which is the default is clicked show This
<ThemeProvider theme = {theme}>
<CountryPicker handleCountryChange={this.handleCountryChange} />
<CountryCards CountryData = {CountryData} CountryYesterdayData = {CountryYesterdayData}/>
</ThemeProvider>
<Chart countrydailydata ={countrydailydata} />
//If the State Button is clicked show this
<ThemeProvider theme= {theme}>
<StatePicker handleStateChange={this.handleStateChange} />
<StateCards stateData= {stateData} yesterdayStateData = {yesterdayStateData}/>
</ThemeProvider>
//If the City Button is clicked show this
<CityPicker handleCityChange={this.handleCityChange}/>
<CityCard cityData = {cityData}/>
</div>
);

import React from 'react';
import logo from './logo.svg';
import './App.css';
function Statepicker(){
return(
<div>Statepicker</div>
)
}
function Statecards(){
return(
<div>Statecards</div>
)
}
function Countrypicker(){
return(
<div>Countrypicker</div>
)
}
function Countrycards(){
return(
<div>Countrycards</div>
)
}
class ThemeProvider extends React.Component{
constructor(props){
super(props);
this.state={country:true,states:false}
}
renderCountryOrState=()=>{
if(this.state.states){
return(<React.Fragment>
<Statepicker/>
<Statecards/>
</React.Fragment>)
}
return (
<React.Fragment>
<Countrypicker/>
<Countrycards/>
</React.Fragment>
)
}
render(){
return(
<div>
<button onClick={(e)=>{this.setState({country:true,states:false})}}>Select country</button>
<button onClick={(e)=>{this.setState({country:false,states:true})}}>Select state</button>
{this.renderCountryOrState()}
</div>
)
}
}
function App() {
return (
<ThemeProvider/>
);
}
export default App;

import React from "react";
import { Button, View } from "react-native";
import styles from "./App.module.css";
import {View} from 'react-native'
import image from "./images/covid1.png";
class App extends React.Component {
constructor(props){
super(props);
state = {
CityButton: false,
StateButton: false,
CountryButton: false
};
}
render() {
{ CountryButton, StateButton, CityButton } = this.state;
return (
<view>
<div className={styles.container}>
<img className={styles.image} src={image} alt="COVID-19" />
<Button title="Country Mode" onPress={() =>
this.setState({CountryButton: true}
)} />
<Button title="State Mode" onPress={() =>
this.setState({StateButton: true}
)} />
<Button title="County Mode" onPress={() =>
this.setState({CityButton: true}
)} />
{CountryButton && <div> Hello </div>}
{StateButton && <div> Hello </div>}
{CityButton && <div> Hello </div>}
</div>
</view>
);
}
}
export default App;

Related

how to reload component back to original state when a prop changes in react

I have a prop called props.currPage. It updates depending on what button is pushed. Whenever a button is pushed, I'd like part of the component to reset back to its original state.
Currently, I cannot get the "listen to this page" button to reappear when i props changes.
Here is the codesandbox.
Below is the header.js file. If I click "listen to this page" it displays an audio player. If I click either button "one" "two" or "three" (that's part of another component) the audio player should go away, and "listen to this page" should reappear:
import React, { useState } from "react";
import ReactPlayer from "./ReactPlayerEx";
import { Button } from "#chakra-ui/react";
function Header(props) {
const [showAudio, setAudio] = useState(0);
return (
<>
{/* <Audio currPage={props.currPage} /> */}
<div onClick={setAudio}>
{showAudio ? (
<ReactPlayer currPage={props.currPage} />
) : (
<Button border={0}> Listen to this Page</Button>
)}{" "}
</div>
</>
);
}
export default Header;
Here is the audio player, ReactPlayerEx.js that will render when "listen to this page" is clicked
import React, { useEffect, useState } from "react";
import ReactPlayer from "react-player";
function RP(props) {
const url =
// "github.com/cre8ture/audioFilesForBL/raw/main/1.mp3"
"https://github.com/cre8ture/audioFilesForBL/blob/main/" +
props.currPage +
".mp3?raw=true";
return (
<div>
<ReactPlayer
url={url}
// "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"
width="200x"
height="50px"
// style={{"textAlign": "left", "color": "red", "backgroundColor": "green"}}
// light
// playIcon = {<Button border={0} borderRadius={20} p={8}><Play/> Listen to this Page </Button>}
playing={false}
controls={true}
/>
</div>
);
}
export default RP;
Here are the three buttons component, threeButtons,js
import React from "react";
function Tabs(props) {
return (
<>
<button onClick={() => props.handleChangeProps(1)}>ONE</button>
<br />
<button onClick={() => props.handleChangeProps(2)}>TWO</button>
<br />
<button onClick={() => props.handleChangeProps(3)}>THRE</button>
</>
);
}
export default Tabs;
And here is the App.js
import React, { useState } from "react";
import Header from "./components/header";
import ConceptTabs from "./components/threeButtons";
function App() {
const [pageID, setPageID] = useState(0);
// goes to ConceptTabs
let handleChange = (id) => {
console.log("clicked", id);
setPageID(id);
return id;
};
console.log("pageID", pageID);
return (
<>
<Header currPage={pageID} />
<br />
<ConceptTabs handleChangeProps={handleChange} />
<br />
{/* <ReactPlayer /> */}
</>
);
}
export default App;
thank you. I believe my issue is a poor knowledge of useEffect(). I'm quite new to React.
Add useEffect which will trigger everytime when props.currPage changes and sets the ReactPlayer visibility to false, only if it's already true.
import React, { useState, useEffect } from "react";
import ReactPlayer from "./ReactPlayerEx";
import { Button } from "#chakra-ui/react";
function Header(props) {
const [showAudio, setAudio] = useState(false);
useEffect(() => {
if (showAudio) setAudio(false);
}, [props.currPage]);
return (
<>
{/* <Audio currPage={props.currPage} /> */}
<div>
{showAudio ? (
<ReactPlayer currPage={props.currPage} />
) : (
<Button border={0} onClick={() => setAudio(true)}>
Listen to this Page
</Button>
)}
</div>
</>
);
}
export default Header;

Not able to call onChange function of a TextInput in Redux, React JS

I am working on an app with React and Redux and displaying some data from API in TextInput control. But now I am not able to edit the data in the TextInput. Following is my complete code of the class:
import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import Article from "grommet/components/Article";
import Box from "grommet/components/Box";
import Button from "grommet/components/Button";
import Header from "grommet/components/Header";
import Heading from "grommet/components/Heading";
import Section from "grommet/components/Section";
import AdminMenu from "../../components/Nav/Admin";
import NavControl from "../../components/Nav/Control";
import { getMessage } from "grommet/utils/Intl";
import Notices from "../../components/Notices";
import CheckBox from "grommet/components/CheckBox";
import TextInput from "grommet/components/TextInput";
import { pageLoaded } from "../utils";
import {
recognitionSettingsLoaded,
recognitionSettingsSaved,
} from "../../actions/settings-recognition";
import dashboard from "../../reducers/dashboard";
class Settings extends Component {
constructor(props) {
super(props);
this.handleDaysChange = this.handleDaysChange.bind(this);
this.handleActiveChange = this.handleActiveChange.bind(this);
}
componentDidMount() {
const { dispatch, settingRecognition } = this.props;
console.log(this.props.state);
console.log(dashboard);
dispatch(recognitionSettingsLoaded("2"));
pageLoaded("Configuration");
}
onSave() {
const { survey, dispatch } = this.props;
dispatch(
recognitionSettingsSaved(
this.props.settingRecognition.days,
this.props.settingRecognition.active
)
);
}
handleDaysChange(e) {
const days = e.target.value;
settingRecognition.days = days;
}
handleActiveChange(e) {
const active = e.target.value;
settingRecognition.active = active;
}
render() {
const { dispatch, settingRecognition } = this.props;
console.log("render method");
console.log(settingRecognition);
const { intl } = this.context;
return (
<Article primary={true}>
<Header
direction="row"
justify="between"
size="large"
pad={{ horizontal: "medium", between: "small" }}
>
<NavControl name={getMessage(intl, "Configuration")} />
<AdminMenu />
</Header>
<Box pad={{ horizontal: "medium", vertical: "medium" }}>
<Heading tag="h4" margin="none">
{getMessage(intl, "RecognitionLifetime")}
</Heading>
<Heading tag="h5" margin="none">
{getMessage(intl, "DefineIsRecognitionTemporary")}
</Heading>
<Box direction="row">
<CheckBox
toggle={true}
checked={settingRecognition.active}
onChange={this.handleActiveChange}
/>{" "}
<Heading tag="h3" margin="none">
{getMessage(intl, "NewUserActive")}
</Heading>
</Box>
<Heading tag="h3" margin="none">
{getMessage(intl, "HideAfter")}
</Heading>
<Box direction="row">
<TextInput
placeholder="type here"
value={settingRecognition.days.toString()}
onChange={this.handleDaysChange}
/>{" "}
<Heading tag="h3" margin="none">
{getMessage(intl, "Days")}
</Heading>
</Box>
<Button
path="/recognition-settings"
label={getMessage(intl, "NewUserSave")}
primary={true}
onClick={() => {
this.onSave();
}}
/>
</Box>
<Notices />
</Article>
);
}
}
Settings.propTypes = {
dispatch: PropTypes.func.isRequired,
settingRecognition: PropTypes.object.isRequired,
};
Settings.contextTypes = {
intl: PropTypes.object,
};
const mapStateToProps = (state) => ({
settingRecognition: state.settingRecognition,
});
export default connect(mapStateToProps)(Settings);
I have created handleDaysChange function which should run on the text change of TextInput control. I have done similar thing for the checkbox and that works fine but I am not able to get it working for the TextInput.
You are not binding your change events.
Try this....
class Settings extends Component {
constructor(props){
super(props);
this.handleDaysChange = this.handleDaysChange.bind(this);
this.handleActiveChange = this.handleActiveChange.bind(this);
}
componentDidMount(){
....
}
......
}
and change this
<CheckBox
toggle={true}
checked={settingRecognition.active}
onChange={(e) => this.handleActiveChange(e)}
/>
To this
<CheckBox
toggle={true}
checked={settingRecognition.active}
onChange={this.handleActiveChange}
/>
same for text input
<TextInput
placeholder="type here"
value={settingRecognition.days.toString()}
onChange={this.handleDaysChange}
/>
You need to set up two-way-binding so that the content of the textInput reflects the prop that you set in your onChange function. Try giving your textInput a property of value={this.settingRecognition.days}

how to use props in a "depth 2" hierarchy

I'm trying to use the props of the App.js file into DishDetailComponent.js but i have other component in the medium of these two, the assigment say:
In this task you will be adding a new DishdetailComponent to your React application and include the component into the menu component's view so that the details of a specific dish are displayed there:
Replace the card showing the selected dish in MenuComponent's view with the DishdetailComponent, and make sure to pass the selected dish information as props to the DishdetailComponent.
Create a new DishDetail class in a file named DishdetailComponent.js in the components folder
Export the DishDetail class from this file so that it can be imported in MenuComponent.js and used to construct the view of the selected dish.
Return a from the render() function. This should use the Bootstrap row class to position the content within the . This div will display both the details of the dish in a Card and the list of comments side-by-side for medium to extra large screens, but will stack them for xs and sm screens.
The card should be enclosed inside a appropriate Bootstrap column classes so that it occupies the entire 12 columns for the xs and sm screen sizes, and 5 columns for md screens and above. Also apply a class of m-1 to this div.
The comments should be enclosed in a to which you apply appropriate column classes so that it occupies the entire 12 columns for the xs and sm screen sizes, and 5 columns for md screens and above. Also apply a class of m-1 to this div.
If the dish is null then you should return an empty
App.js
import MenuComponent from './component/MenuComponent'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
dishes: DISHES
}
}
render() {
return (
<div className="app">
<Navbar dark color="primary">
<div className="container">
<NavbarBrand href="/">
Ristorante Con Fusion
</NavbarBrand>
</div>
</Navbar>
<MenuComponent
dishes={this.state.dishes}
/>
</div>
);
}
}
export default App;
MenuComponent.js
import React, { Component } from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from 'reactstrap';
/* Components */
import DishDetail from './DishDetailComponent'
class MenuComponent extends Component {
constructor(props) {
super(props);
this.state = {
selectedDish: null
};
console.log('Menu Component constructor is invoked');
}
componentDidMount() {
console.log('Menu Component componentDidMount is invoked')
}
onDishSelect(dish) {
this.setState({ selectedDish: dish });
}
renderDish(dish) {
if (dish != null) {
return (
<Card >
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
)
} else {
return (
<div>
</div>
)
}
}
render() {
const menu = this.props.dishes.map((dish) => { /* This is a prop that are provided from App.js
in the render() <MenuComponent dishes={}> */
return (
<div key={dish.id} className="col-12 col-md-5 m-1">
<Card onClick={() => this.onDishSelect(dish)}>
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle><strong>{dish.name}</strong></CardTitle>
</CardImgOverlay>
</Card>
</div>
);
});
console.log('Menu component render is invoked')
return (
<div className="container">
<div className="row">
{menu}
</div>
<div className="row col-12 col-md-5 col-lg-5 mr-1">
<div>
<Card className="">
{this.renderDish(this.state.selectedDish)}
</Card>
</div>
</div>
</div>
);
}
}
export default MenuComponent;
DishDetailComponent.js
/* Modules */
import React, { Component } from 'react';
import { Card, CardText, CardBody, CardTitle, CardImg } from 'reactstrap';
/* Components */
/* Styles */
class DishDetailComponent extends Component {
constructor(props) {
super(props)
this.state = {
}
}
onDishSelect(dish) {
this.setState({ selectedDish: dish })
}
renderDish(dish) {
if (dish != null) {
return (
<Card >
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
)
} else {
return (
<div>
</div>
)
}
}
render() {
const comment = this.props.dishes.map((dish) => {
return (
<div key={dish.key}>
<ul className="unorder-list">
{dish.comments}
</ul>
</div>
)
})
return (
<div className="row col-12 col-lg-5 m-1">
<Card >
HEre i have to put the info the name the img and these things
</Card>
</div>
);
}
}
export default DishDetailComponent;
This is the last component im tried to do it but i dont know how to use very well props!
if you want see my git https://gitlab.com/folayao/react-coursera-felipe

My modal doesn't show when I click a button

Here I have my modal component. I am making an app that I want a button to open this modal that I use in multiple places like opening a preview or deleting options.
import React from 'react';
import ReactDOM from 'react-dom';
import { CSSTransition } from 'react-transition-group';
import Backdrop from '../Backdrop/Backdrop';
import '../Modal/Modal.css';
const ModalOverlay = (props) => {
const content = (
<div className={`modal ${props.className}`} style={props.style}>
<header className={`modal__header ${props.headerClass}`}>
<h2>{props.header}</h2>
</header>
<form
onSubmit={
props.onSubmit ? props.onSubmit : (event) => event.preventDefault()
}
>
<div className={`modal__content ${props.contentClass}`}>
{props.children}
</div>
<footer className={`modal__footer ${props.footerClass}`}>
{props.footer}
</footer>
</form>
</div>
);
return ReactDOM.createPortal(content, document.getElementById('modal-hook'));
};
const Modal = (props) => {
return (
<React.Fragment>
{props.show && <Backdrop onClick={props.onCancel} />}
<CSSTransition
in={props.show}
mountOnEnter
unmountOnExit
timeout={200}
classNames="modal"
>
<ModalOverlay {...props} />
</CSSTransition>
</React.Fragment>
);
};
export default Modal;
And here I use this modal for showing up deleting options.
const DocumentItem = (props) => {
const [showConfirmModal, setShowConfirmModal] = useState(false);
const showDeleteWarningHandler = () => {
setShowConfirmModal(true);
};
const calcelDeleteHandler = () => {
setShowConfirmModal(false);
};
const confirmDeleteHandler = () => {
setShowConfirmModal(false);
console.log('Delete!');
};
return (
<React.Fragment>
<Modal
show={showConfirmModal}
onCancel={calcelDeleteHandler}
header="Are you sure?"
footerClass="document-item__modal-actions"
footer={
<React.Fragment>
<Button inverse onClick={calcelDeleteHandler}>
CANCEL
</Button>
<Button danger onClick={confirmDeleteHandler}>
DELETE
</Button>
</React.Fragment>
}
>
<p>
Do you want to proceed and delete this document? Please note that it
can't be undone thereafter.
</p>
</Modal>
</React.Fragment>
);
};
I don't understand why my screen goes all black, transparent but my modal doesn't show.
How can I fix this problem?

perform onclick event in reactjs

I am trying to make an application using reactjs.below is the code which present in my main app.js:
class App extends Component {
return (
<div>
<ExampleTable
header={() => <TopBar/>}
/>
<AddExampleModal/>
<ChartModal/>
<CompatibilityAlert/>
</div>
)
}
}
where Top Bat,AddExampleModal , ChartModal and CompatibilityAlert are loaded from other js files.
Chartmodal contains:
class ChartModal extends Component{
constructor(props){
super(props)
}
render(){
return(
<Modal
onOk={()=>console.log('ok')}
onCancel={()=>console.log('cancel')}
visible={true}
okText={'ok'}
cancelText={'cancel'}
confirmLoading={false}
title="Intent distribution chart"
>
<h1>HOWDY</h1>
<TreeMap
data={chartData}
width={400}
valueUnit={'count'}
/>
</Modal>
)
}
}
Topbar contains :
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
// onClick={() => changechartshow()}
>
Show Graph
</Button>
)
}
}
The thing is that in the app file,i want to toggle the visibility of chartmodal using the button in the topbar.
App
class App extends Component {
constructor() {
this.state = {
isVisible: true
}
}
toggleVisibility = () => this.setState({isVisible: !this.state.isVisible})
render () {
const {isVisible} = this.state;
return (
<div>
<ExampleTable
header={() => <TopBar toggleVisibility =
{this.toggleVisibility.bind(this)}
/>}
<AddExampleModal/>
<ChartModal isVisible={isVisible}/>
<CompatibilityAlert/>
</div>
);
}
}
TopBar
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
onClick={() => this.props.toggleVisibility()}
>
Show Graph
</Button>
)
}
}
ChartModal - Pass the state to visible attribute
class ChartModal extends Component{
constructor(props){
super(props)
}
render(){
return(
<Modal
onOk={()=>console.log('ok')}
onCancel={()=>console.log('cancel')}
visible={this.props.isVisible}
okText={'ok'}
cancelText={'cancel'}
confirmLoading={false}
title="Intent distribution chart"
>
<h1>HOWDY</h1>
<TreeMap
data={chartData}
width={400}
valueUnit={'count'}
/>
</Modal>
)
}
}
You can add a state in your App component and pass an handler to update the state from the TopBar component. Based on this state you can toggle the visibility of ChartModal.
class App extends Component {
state = {
isVisible: true
}
toggleVisibility = () => {
this.setState(prevState => ({isVisible: !prevState.isVisible}))
}
return (
<div>
<ExampleTable
header={() => <TopBar toggleVisibility={this.toggleVisibility}/>}
/>
<AddExampleModal/>
{this.state.isVisible ? <ChartModal/>: null }
<CompatibilityAlert/>
</div>
)
}
}
Now in your TopBar you will call this function as
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
onClick={() => this.props.toggleVisibility()}
>
Show Graph
</Button>
)
}
}
Read the React docs here on Lifting the state up for a detailed explanation

Categories

Resources