import React, { useEffect, useState } from "react";
import './Menu.css'
export default function Menu() {
const [classes, setClasses] = useState('container')
return (
<div>
<p>Click on the Menu Icon to transform it to "X":</p>
<div className={classes} onClick={() => setClasses("container change")}>
<div className="bar1"></div>
<div className="bar2"></div>
<div className="bar3"></div>
</div>
</div>
)
}
It works now because of one of the given solutions, but when I click on the icon again, it doesn't go back to the original state. How can I fix that?
I got this menu example from here: https://www.w3schools.com/howto/howto_css_menu_icon.asp
You might want to use useState hook to dynamically change your element's class name.
import React from 'react'
import './Menu.css'
export default function Menu() {
const [classes, setClasses] = useState('container')
return (
<div>
<p>Click on the Menu Icon to transform it to "X":</p>
<div className={classes} onClick={() => setClasses("container change")}>
<div className="bar1"></div>
<div className="bar2"></div>
<div className="bar3"></div>
</div>
</div>
)
}
Something like this maybe. But I'm sure there are other ways too.
if you want to toggle back and forth;
setClasses(prevClasses => {
if (prevClasses = "container") return "container change"
else { return "container" }
})
YOu can use state to check what is the current state (user clicked or not), and then can plan behavior accordingly:
export default function Menu() {
const [toggle, setToggle] = useState(false);
return (
<div>
<p>Click on the Menu Icon to transform it to "X":</p>
<div
// If toggle is true, set className to 'change' else 'contianer'
className={toggle ? 'change' : 'container'}
// toggle state (toggle) on click
onClick={() => setToggle(prevToggle => !prevToggle)}
>
<div className='bar1'></div>
<div className='bar2'></div>
<div className='bar3'></div>
</div>
</div>
);
}
Related
I am trying to toggle react state after the button click. After clicking button Work From Office should change to work From Home and vice versa. But it is not working. What am I dong wrong? I am able to change only once. Can we do with if statement? What is simple way?
** React **
import React, { Component } from 'react';
import './ChangeSchedule.css';
class ChangeSchedule extends Component {
constructor(){
super()
this.state = {
// work:'from office'
workFromOffice:true
}
}
changeMyWorkPlace(){
this.setState({
// work:'from Home'
workFromOffice:!this.state.workFromOffice
})
}
render(){
return(
<div>
<div class="schedule change">
<h3>Emplyoee Name: </h3>
<p>Today Pooja is work {this.state.work}</p>
{/* <button class="chageScheduleBtn " onClick = {()=> this.changeMyWorkPlace()}> Change My Schedule </button> */}
<button class="chageScheduleBtn " onClick = {()=> this.workFromOffice() ?'Home': 'Office'}> Change My Schedule </button>
</div>
</div>
)
}
}
export default ChangeSchedule;
You can use a ternary expression to display content for each state.
For example:
{this.state.workFromOffice ? " from Office" : " from Home"}
Now this button should work as you expect:
<button class="chageScheduleBtn" onClick={()=> this.changeMyWorkPlace()}>
Change My Schedule
</button>
See codesandbox for fully working example
You could do it as below. Just change the status when the click happen. And inside the button, use a ternary expression. Like so:
import { Component } from "react";
import "./ChangeSchedule.css";
class ChangeSchedule extends Component {
constructor() {
super();
this.state = {
// work:'from office'
workFromOffice: true,
};
}
changeMyWorkPlace() {
this.setState({
// work:'from Home'
workFromOffice: !this.state.workFromOffice,
});
}
render() {
return (
<div>
<div class="schedule change">
<h3>Emplyoee Name: </h3>
<p>Today Pooja is work {this.state.work}</p>
<button class="chageScheduleBtn " onClick={() => this.workFromOffice()}>
{this.state.workFromOffice ? "Work From Home" : "Work From Office"}
</button>
</div>
</div>
);
}
}
export default ChangeSchedule;
The answer is in the way you're structuring your state. You can make it really simple by just using one entry of the state - workFromOffice. Then, your click handler should care only about changing that state value to the opposite of what was set before. Example:
onClick={() => this.setState({ workFromOffice: !this.state.workFromOffice })}
When the changeMyWorkPlace function created, it captures your initial state and uses it everytime you run the function so only works once. You should instruct react to use up to date state.
try this way.
changeMyWorkPlace(){
this.setState((previousState) => ({
// work:'from Home'
workFromOffice:!previousState.workFromOffice
}))
}
Objects
Favourites
im trying to do a website witch react and i use an api to recieve data. The Data i recieved gets put into a list and then i produce a button for every item in this list. Now i also produce a check box for every item in the list, but the production is in a seperate component. what i want to do ist that, if the checkbox of one item gets checked, the item should be stored in a cache and put out again as an button on a seperate page. My Question now is how do i do that?
Thank you in advance.
This is where i produce the checkbox:
import React from "react";
export default function Favcheck() {
return (
<>
<div class="favcheck">
Favorit
<input type="checkbox" name="name" class="checkbox" id="heart" />
</div>
</>
);
}
this is where the buttons are made:
import axios from "axios";
import * as React from "react";
import Favcheck from "./favcheck.jsx";
import Mensapage from "./mensapage.jsx";
import site from "./home.jsx";
export default function Mensbuttons(props) {
return (
<>
<div class="formcontainer">
<form method="get" action="/mensapage" id="mensaform">
<button type="submit" class="mensabutton" key={props.key}>
<div class="mensatext">{props.name}</div>
</button>
<br></br>
<Favcheck />
</form>
</div>
</>
);
}
and this is where the buttons are used:
import React,{ useState, useEffect } from "react";
import axios from 'axios';
import Nav from "./nav.jsx";
import Mensbuttons from "./mensbuttons.jsx";
export default function Home(props) {
let site="test";
const[posts,setPosts] = useState([])
useEffect(()=>{
axios.get('https://openmensa.org/api/v2/canteens?near[lat]=52.517037&near[lng]=13.38886&near[dist]=15')
.then(res =>{
setPosts(res.data)
})
.catch(err =>{
console.log(err)
})
},[])
console.log(posts);
return (
<>
<Nav />
<div class="header">
<h1>Mensen</h1>
</div>
{posts.map((list) => {
return <Mensbuttons name={list.name} key={list.id} />;
})}
</>
);
}
here are some mockup pictures
i want to get specific objects to the favourites page by checking the checkbox
here are the favourites
here are the buttons with checkboxes
I'm trying to fetch some data from my database with some simple to-dos. However I cant seem to map them out into a list on my site.
I keep getting errors like: todoFromServer.map is not a function or that todoFromServer is not an array etc.
My current code looks like this:
import apiFacade from "../api/apiFacade";
import React, { useState, useEffect } from "react";
import {Form, FormGroup, Label, Input, Button} from "reactstrap"
export default function SecurePage() {
const [todoFromServer, setTodoFromServer] = useState("Waiting...");
useEffect(() => {
apiFacade.getTodo().then((data) => setTodoFromServer(data));
}, []);
return (
<div className="container-fluid padding">
<div className="row">
<div className="col-3"></div>
<div className="col-6 text-center">
<Form>
<FormGroup>
<h3 className="mt-5">Todos</h3>
<Input type="text" placeholder="Enter Todo"></Input>
</FormGroup>
<Button type="submit">Add</Button>
</Form>
<div>
{todoFromServer.map(() => (
<div>{todoFromServer.todoText}</div>
))}
</div>
</div>
</div>
</div>
);
}
The data I trying to fetch should come out as json looking like this:
I'm kind of lost.. Hope someone can help me out
to be clear - I want the data mapped out on a list with a delete button next to it...
const [todoFromServer, setTodoFromServer] = useState([]); // <=== initialize this as an empty array.
useEffect(() => {
apiFacade.getTodo().then((data) => setTodoFromServer(data)); // Make sure data returned from Promise resolve is indeed an array
}, []);
You want to read todoText of each todo's inside your array item so you would do something like this.
{todoFromServer.length ? todoFromServer.map((todo) => (
<div>{todo.todoText}</div>
)) : "Waiting..."}
For additional reference, take a look at Array.map usage here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
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>
)
I've used React for a couple of weeks now but I have this simple problem that I can't seem to wrap my head around. It's about creating new html elements.
I would just like to know in general if the way that I went about it, is the "right way" or is there another preferred way to create new html element with a click function.
For some reason this problem took awhile for me to figure out and it still feels a bit strange, that's why I'm asking.
Thanks in advance!
import React, { Component } from 'react';
import './Overview.css';
import Project from './Project';
class Overview extends Component {
constructor() {
super()
this.state = {
itemArray: []
}
}
createProject() {
const item = this.state.itemArray;
item.push(
<div>
<h2>Title</h2>
<p>text</p>
</div>
)
this.setState({itemArray: item})
//console.log(this.state)
}
render() {
return (
<div className="Overview">
<p>Overview</p>
<button onClick={this.createProject.bind(this)}>New Project</button>
<Project />
<div>
{this.state.itemArray.map((item, index) => {
return <div className="box" key={index}>{item}</div>
})}
</div>
</div>
);
}
}
export default Overview;
No, this is not a correct approach. You shouldn't be generating HTML elements like that, nor keep them in state - it is against React to manipulate DOM like that. You won't be able to utilize Virtual DOM is the first thing that I can think of.
What you should do instead is keep all data that is needed for rendering in state and then generate the HTML element from there, for instance
createProject() {
const item = this.state.itemArray;
const title = '';
const text = '';
item.push({ title, text })
this.setState({itemArray: item})
}
render() {
return (
<div className="Overview">
<p>Overview</p>
<button onClick={this.createProject.bind(this)}>New Project</button>
<Project />
<div>
{this.state.itemArray.map((item, index) => {
return (
<div className="box" key={index}>
<div>
<h2>{item.title}</h2>
<p>{item.text}</p>
</div>
</div>
)
})}
</div>
</div>
);
}