React how to: replace only one component on click (dynamic UI) - html

Using react.js I want to make a dynamic UI, I have something like this:
<div>
<appbar component />
<drawer (sidebar) comopnent /> <!-- <--has buttons -->
<content component> <!-- <-- component to replace or re-render -->
<footer component>
</div>
Then I try to use an state to save and change the "" like this:
const [renderView, setRenderView] = useState("<Home />");
/* onclick call this function and pass referenced component ej: <reports /> */
function changeContent(view){
setRenderView(view);
return(
<Suspense fallback={renderLoader()}>
{view}
</Suspense>
);
}
Now, how to replace the " content component " with the new one?.
Thanks for your comments.

i made this bassed on suggestions, its working, but im not using class just functions
function Dashboard(props) {
/* lazy loading */
const renderLoader = () => <p>Loading...!?¡?</p>;
/* lazy components */
const Initial = () => (
<Suspense fallback={renderLoader()}>
<InitialComponent />
</Suspense>
)
const Reports = () => (
<Suspense fallback={renderLoader()}>
<ReportsComponent />
</Suspense>
)
const Cards = () => (
<Suspense fallback={renderLoader()}>
<CardsComponent />
</Suspense>
)
/* set view state */
const [renderView, setRenderView] = useState(Initial());
function changeContent(view){
setRenderView(view);
}
const test = (cosa) => {
console.log(cosa);
}
/* style things*/
const classes = useStyles();
const fixedHeightPaper = clsx(classes.paper, classes.fixedHeight);
return (
<div className={classes.root}>
<CssBaseline />
<UIappbar />
<UIsidebar />
<main className="contentWrapper">
<Grid container spacing={3}>
<Grid item xs={12} md={8} lg={9}>
<div>
<Button onClick={() => changeContent(Reports())}>Reports view</Button>
</div>
<div>
<Button onClick={() => changeContent(Cards())}>Cards view</Button>
</div>
</Grid>
<Grid item xs={12} md={8} lg={9}>
<Paper className={fixedHeightPaper}>
{renderView}
</Paper>
</Grid>
</Grid>
</main>
</div>
);
}
Now i need to call "changeContent()" that has the method to change {renderView} need to call it from a child
dont know how to pass props without class format (im using functions only)
should i change to class with constructor format?

Related

Title attribute for react native <View>, <TouchableOpacity> same as that of <div titile="abc">

We are using react native for creating web UI as well. Here my requirement is to pass title attribute in <View/> or <Text/> component same as that of <div title="abc"> tag in HTML. Could someone please suggest and help me out.
<View>
<Text>ABC</Text>
<View/>
Something like this.
If it needs to be a variable (and it is called title):
<View>
<Text>{title}</Text>
<View/>
Same goes for TouchableOpacity.
What do you mean by using the title attribute for "View"?
here you can find every prop that "View" accepts.
Also, you can find out which props are going to use for the other React native Components, in the same way.
I think you want to know how to send params like the title to a component that we create on our own, like a container in our app:
// Container.js
import ...
.
.
.
const Container = (props) => {
// Destructuring the props
const {title, children} = props;
return (
<View style = {styles.container}>
<View style = {styles.header}> // header of your container
<Text>{title}</Text> // use title here
</View>
{children} // body of your container
</View>
)
}
export default Container;
const styles = StyleSheet.create({
// styles here
})
// Home.js
import ...
import Container from './Container.js'
.
.
.
const Home = (props) => {
return(
<Container title = 'Home'> // now we can send this param to our Container
// body as Container Children goes here
</Container>
)
}

Unresponsive page layout with ReactMapGL in ReactJs

I have a ReactMapGL component in my page that is stored above the footer and below the navbar. In my initial screen from my desktop the layout looks fine, but when I inspect element to make the screen size smaller, the layout becomes unresponsive.
So far this is my code for this particular page:
export default function Map({posts}) {
const [viewport, setViewport] = useState({
latitude: 45.4211,
longitude: -75.6938,
width:"100vw",
height:"100vh",
zoom: 10,
});
const [selectedProperty, setSelectedProperty] = useState(null)
return (
<div>
<ReactMapGL {...viewport} mapboxApiAccessToken="//mykey"
mapStyle="mapbox://styles/jay/cks5xkaa892cp17o5hyxcuu0z"
onViewportChange={viewport => {
setViewport(viewport);
}}>
{
posts &&
posts.map((maps) => (
<Marker key={maps.id} latitude={maps.Latitude} longitude={maps.Longitude}>
<button className="marker-btn" onClick={e => {
e.preventDefault();
setSelectedProperty(maps);
}}>
<img src="placeholder.svg"/>
</button>
</Marker>
))}
{selectedProperty ? (
<Popup latitude={selectedProperty.Latitude} longitude={selectedProperty.Longitude}
onClose={() => {setSelectedProperty(null);}}>
<h1>{selectedProperty.Title}</h1>
</Popup>) : null}
</ReactMapGL>
</div>
);
}
For the Navbar and footer I have copy pasted the html and css from here.

How to set ref to an unrendered element

I have a login page where I'm placing a button "Watch the video". On click of the button, I'm hiding the button and displaying a video.
Now my requirement is to start playing the video as soon as it displays without having to click the play button.
I'm trying to use refs and somehow I'm unable to set the ref to my video element.
Is there any way to set the refs to unrendered elements in componentDidUpdate?
Please help me!
Following is my code
export default class NewLoginPage extends Component {
constructor(props) {
this.vidRef = React.createRef();
this.state = {
showVideo: false
};
}
handleVideoClick = () => {
this.setState({ showVideo: true })
this.vidRef.current.play();
}
handleCloseClick = () =>{
this.setState({ showVideo: false })
}
render() {
let language_labels = labels["english_labels"]
console.log(labels)
console.log(language_labels)
return (
<div className="container-fluid no-padding">
<div className="new-login-div">
<AppBar className="app-bar">
<Toolbar className="tool-bar">
<img src={pmiLogo} />
{/* <NavLink to="/" id="invoice_upload">LOG OUT</NavLink> */}
{/* <Button className="logout-btn">REGISTER</Button> */}
</Toolbar>
</AppBar>
<Grid container>
<Grid item xs={4}>
<h1 className="welcome-heading">Self Service Portal</h1>
<TextField
className="id-field"
placeholder="Email"
inputProps={{
style: {
color: "#fff",
paddingLeft: "5px"
}
}}
/>
<br />
<Button className="login-btn" endIcon={<ArrowForwardIcon />}>Log In</Button>
</Grid>
<Grid item xs={8}>
<div className="video-div">
{this.state.showVideo && <div>
<IconButton className="close-btn" onClick={(event) => this.handleCloseClick()}>
<CloseIcon />
</IconButton>
<video ref={ref => { this.vidRef = ref }} width="500" height="285" controls className="video-container">
<source src={exampleVid} type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>}
{!this.state.showVideo && <div className="intro-div">
<h5 className="intro-text">
Supporting the vitality and survival of US small businesses—who employ nearly half of the American workforce—is especially critical now. Let’s not forget just how essential they are.
</h5>
<Button
disableRipple={true}
className="video-button"
startIcon={<PlayArrowIcon className="play-icon" />}
onClick={(event) => this.handleVideoClick()}
>
Watch video
</Button>
<br />
<Button
disableRipple={true}
className="reg-button"
startIcon={<ChevronRightIcon className="play-icon" />}>
Register
</Button>
</div>}
</div>
</Grid>
</Grid>
</div>
</div>
);
}
}
React ref property is used to access DOM element reference.
If element is not rendered then DOM element is not created (deleted).
Thus you can't get a ref of something that doesn't exist.
You don't need to use a ref to do that, you can add the autoplay html property to your <video>
for details on autoplay
You can't make use of a ref to an element that is not yet rendered as Anton explained in his answer, the ref.current will be null.
However, it is suggested that you create a separate component for the video and it's logic from that of the login, not only it will solve the issue (the this.state.showVideo condition will stay in the parent component) but it is also how React components should be, for more details refer to this.

REACT - Image gallery

I'm retrieving images from the database in REACT and have created a holder for an image with thumbnails at the bottom.
I would like to know how I can make the interface behave like eCom sites, whereupon clicking the thumbnail, its respective image is loaded in the bigger area.
Below is the REACT code.
import React from "react";
import { Link } from "react-router-dom";
import ImageList from "../ImageList";
const ProductDetails = props => {
const images = require.context(
"../../../strapui/app/public/uploads",
true,
/\.jpg$/
);
const keys = images.keys();
const svgsArray = keys.map(key => images(key));
return(
<div className="desContainer ">
<div className="desimgContainer ">
<ImageList
styles="heroImage"
imagePath={props.selectedItem[0].image[0]}
svgsArray={svgsArray}
/>
</div>
<div className="thumbs">
<ImageList
styles="thumbnail"
imagePath={props.selectedItem[0].image[0]}
svgsArray={svgsArray}
/>
</div>
<div className="thumbs">
<ImageList
styles="thumbnail"
imagePath={props.selectedItem[0].image[1]}
svgsArray={svgsArray}
/>
</div>
<div className="thumbs">
<ImageList
styles="thumbnail"
imagePath={props.selectedItem[0].image[2]}
svgsArray={svgsArray}
/>
</div>
</div>
);
};
export default ProductDetails;
The images are pulled from the database using the following code
import React from "react";
const ImageList = props => {
if (
props.imagePath === undefined ||
props.imagePath === null ||
props.imagePath.length === 0
)
return null;
const path = props.svgsArray.find(
str => str.indexOf(props.imagePath.hash) > 1
);
return <img src={path} alt={props.imagePath.hash} className={props.styles} />;
};
export default ImageList;
I was wondering if I could use a switch case to show the image when a thumbnail is clicked?
will it work? if it will, can you pls direct me how?
Use onClick event and attach it with some function which should do some code magic.
for e.g:
largeSizeImage () {
/* some code logic */
}
return (
<div className="thumbs" onClick={largeSizeImage()}>
<ImageList
styles="thumbnail"
imagePath={props.selectedItem[0].image[1]}
svgsArray={svgsArray}
/>
</div>
)

Show dialog in React - Material UI

I am learning ReactJS. I would like to display dialog when someone clicks on the icon.
Here is the code:
import React, { Component } from 'react';
import { GridList, GridTile } from 'material-ui/GridList';
import FlatButton from 'material-ui/FlatButton';
import Info from 'material-ui/svg-icons/action/info';
import { fullWhite } from 'material-ui/styles/colors';
import Dialog from 'material-ui/Dialog';
import RaisedButton from 'material-ui/RaisedButton';
(... class stuff, handleClose, handleOpen etc.)
showDialoga() {
const actions = [
<FlatButton
label="Cancel"
primary
onClick={this.handleClose}
/>,
<FlatButton
label="Submit"
primary
keyboardFocused
onClick={this.handleClose}
/>,
];
return (
<div>
<RaisedButton label="Dialog" onClick={this.handleOpen} />
<Dialog
title="Dialog With Actions"
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose}
>
The actions in this window were passed in as an array of React objects.
</Dialog>
</div>
);
}
render() {
console.log(this.props);
return (
<div style={styles.root}>
<GridList
cellHeight={180}
style={styles.gridList}
padding={10}
>
{this.props.movieData.map(tile => (
<GridTile
key={tile.original_image}
title={tile.title}
actionIcon={<FlatButton
icon={<Info color={fullWhite} />}
style={style}
onClick={() => this.showDialoga()}
/>}
>
<img src={tile.original_image} />
</GridTile>
))}
</GridList>
</div>
);
}
}
I am able to pass other function like () => console.log('I am clicked') to onClick although I am not able to pass that showDialoga().
Any idea what is the problem?
I do not believe that's how you are supposed to use dialog.
Instead of passing return of React component on click, try setting the dialog opened state to be true/false. Also do not forget to bind this to the class level if you are using functions to render different components that has event listeners.