React ProgressBar - javascript

Hello I need to setup a progress bar. So when I press on the button progress bar shows, the button and the content inside of it dispears proggress bar starts to go 0 100 and as well shows some text above, and
when it reaches the 100% progress bar disppears and text above, but after that new text shows. Thanks in Advance
import React,{useEffect, useState} from 'react'
import LinearProgress from '#material-ui/core/LinearProgress'
const useStyles = makeStyles({
root: {
width: '100%',
},
});
const Content =(props)=> {
const classes = useStyles();
const[hideContent, setHideContent]= React.useState(false)
const [progress, setProgress] = React.useState(10);
function handleClick12 ()
{setHideEset(true) }
useEffect(() => {
const timer = setInterval(() => {
setProgress((prevProgress) => (prevProgress >= 100 ? 10 : prevProgress + 10));
}, 800);
return () => {
clearInterval(timer);
};
}, []);
return (
{!hideContent &&
<div className='esetNod__info'>
<h3>Hello</h3>
<Button onClick={handleClick12} className='fix__button'variant='outlined'></Button>
<div >
<LinearProgress value={progress} />
</div>
</div>
}
</div>
)
}
export default Content;

I tried to write something for you:
import React, { useState } from "react";
import LinearProgress from "#material-ui/core/LinearProgress";
const Content = () => {
const [isLoading, setIsLoading] = useState(false);
const [hasLoaded, setHasLoaded] = useState(false);
const [progress, setProgress] = useState(0);
const handleClick = () => {
setIsLoading(true);
const interval = setInterval(() => {
setProgress((prevProgress) => {
const next = prevProgress + 10;
if (next === 100) {
clearInterval(interval);
setIsLoading(false);
setHasLoaded(true);
}
return next;
});
}, 800);
};
if (!isLoading && !hasLoaded) {
return (
<div className="esetNod__info">
<h3>Pre load content</h3>
<button onClick={handleClick} className="fix__button">
Load Content
</button>
</div>
);
} else if (isLoading && !hasLoaded) {
return (
<diV>
<h3>Loading content</h3>
<LinearProgress value={progress} />
</diV>
);
} else {
return (
<div>
<h3>Post load content</h3>
</div>
);
}
};
export default Content;

Related

hiding and showing array of images

So I have an array of images, which I would like to hide or show on a click of a button.
right now when I try to hide the image, it will hide the entire array.
import "./main.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "#fortawesome/free-solid-svg-icons";
const Main = ({ galleryImages }) => {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
const [show, toggleShow] = useState(true);
// buttons next to name of diff charts (hide/show chart)
const handleOpenModal = (index) => {
setSlideNumber(index);
setOpenModal(true);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
// const hide = () => {
// setShow(false)
// }
const handleCloseModal = () => {
setOpenModal(false)
}
useEffect(()=> {
setPics(galleryImages)
},[]);
return (
<div>
<button onClick={() => toggleShow(!show)}>toggle: {show ? 'show' : 'hide'}</button>
{show &&
<div>
{pics.map((pic) => {
return (
<div style = {{marginBottom:'100px'}}>
{pic.id}
<img
src={pic.img}
width='500px'
height='500px'
/>
<button onClick ={() => removeImage(pic.id)}>Delete</button>
</div>
)
})}
</div>
I tried making a state component to try to hide and show the images, however it will hide the entire array instead of the individual image
i would add a show var to the galleryImages array and then set it so you get control of each image like this
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import "./main.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "#fortawesome/free-solid-svg-icons";
function Main({ galleryImages }) {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
// buttons next to name of diff charts (hide/show chart)
const toggleShow = ({ id, show }) => {
setPics((oldState) =>
oldState.map((item) => {
if (item.id !== id) return item;
return { ...item, show: !show };
})
);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
useEffect(() => {
setPics(
galleryImages.map((galleryImage) => {
return { ...galleryImage, show: true };
})
);
}, []);
return (
<div>
<div>
{pics.map((pic) => {
return (
<>
<button
onClick={() => toggleShow({ show: pic.show, id: pic.id })}
>
toggle: {pic.show ? "show" : "hide"}
</button>
{pic.show && (
<div style={{ marginBottom: "100px" }}>
{pic.id}
<img src={pic.img} width="500px" height="500px" />
<button onClick={() => removeImage(pic.id)}>Delete</button>
</div>
)}
</>
);
})}
</div>
</div>
);
}
export default Main;
`
If you would like the option to hide individual pics, to accomplish this you are correct in your state component approach.
First you can create a pic component that has its own state with a hide/show button:
export default function Pic({pic}) {
const [showPic, setShowPic] = useState(true);
const handleClick = () => {setShowPic(!showPic)}
return (
<div>
<div style={showPic ? {display : "block"} : {display : "none"}}>
<img
src={pic.img}
width='500px'
height='500px'
/>
</div>
<button onClick={handleClick}>{showPic ? 'Hide' : 'Show'}</button>
</div>
)
}
Next, you can import this component into your main file
import Pic from 'location/Pic.js';
and map each pic to a <Pic> component.
{pics.map((pic) => <Pic pic={pic} key={pic.id}/>)}
Now the images will be shown each with their own Hide/Show button that can toggle their display with the state contained within each <Pic/> component. This is good practice because toggling one image will not cause a re-render of the entire image gallery.

useState defaults appear to rerun after running function on state change, defaults shouldnt run twice

I have the following issue with website where the settings state resets after running more searches. The settings component is show below in the picture, it usually works but if you uncheck a box and then run a few more searches at some point the showAllDividends setting will be set to false, the All dividends component won't be on the screen, but for some reason the checkbox itself is checked (true). This is my first time really working with checkboxes in React, and I think I'm using the onChange feature wrong. Right now I get the event.target.checked boolean, but only onChange.
If that isn't the issue then the most likely cause is the default statements being run again on another render:
const [showMainInfo, setShowMainInfo] = useState(true);
const [showYieldChange, setShowYieldChange] = useState(true);
const [showAllDividends, setShowAllDividends] = useState(true);
the thing is I don't see why the default statements would run more than once, the component isn't being destroyed there's no react router usage. I expected it to keep its current state after the page is first loaded. I think the settings defaults are being rerun, but just don't understand why they would.
I unchecked, checked, unchecked the 'All dividends' checkbox, and it was unchecked when I ran 2 more searches. After the second search the checkbox was checked but the component was gone, because showAllDividends was false
main component SearchPage.js:
import React, {useState, useEffect} from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
import SearchBar from './SearchBar';
import AllDividendsDisplay from './dividend_results_display/AllDividendsDisplay';
import DividendResultsDisplay from './dividend_results_display/DividendResultsDisplay';
import SettingsView from './settings/SettingsView';
const HOST = process.env.REACT_APP_HOSTNAME
const PROTOCOL = process.env.REACT_APP_PROTOCOL
const PORT = process.env.REACT_APP_PORT
const BASE_URL = PROTOCOL + '://' + HOST + ':' + PORT
const SearchPage = ({userId}) => {
const DEFAULT_STOCK = 'ibm';
const [term, setTerm] = useState(DEFAULT_STOCK);
const [debouncedTerm, setDebouncedTerm] = useState(DEFAULT_STOCK);
const [loading, setLoading] = useState(false);
const [recentSearches, setRecentSearches] = useState([DEFAULT_STOCK]);
const [dividendsYearsBack, setDividendsYearsBack] = useState('3');
const [debouncedDividendYearsBack, setDebouncedDividendYearsBack] = useState('3');
const [errorMessage, setErrorMessage] = useState('');
const [dividendsData, setDividendsData] = useState(
{
current_price: '',
recent_dividend_rate: '',
current_yield: '',
dividend_change_1_year: '',
dividend_change_3_year: '',
dividend_change_5_year: '',
dividend_change_10_year: '',
all_dividends: [],
name: '',
description: '',
}
)
const [settingsViewVisible, setSettingsViewVisible] = useState(false);
const [showMainInfo, setShowMainInfo] = useState(true);
const [showYieldChange, setShowYieldChange] = useState(true);
const [showAllDividends, setShowAllDividends] = useState(true);
const onTermUpdate = (term) => {
setTerm(term)
}
// TODO: write a custom hook that debounces taking the term and the set debounced term callback
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedTerm(term);
}, 1500);
return () => {
clearTimeout(timerId);
};
}, [term]);
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedDividendYearsBack(dividendsYearsBack);
}, 1500);
return () => {
clearTimeout(timerId);
};
}, [dividendsYearsBack]);
useEffect(() => {runSearch()}, [debouncedTerm]);
useEffect(() => {
// alert(dividendsYearsBack)
if (dividendsYearsBack !== '') {
runSearch();
}
}, [debouncedDividendYearsBack])
useEffect(() => {
console.log("user id changed")
if (userId) {
const user_profile_api_url = BASE_URL + '/users/' + userId
axios.get(user_profile_api_url, {})
.then(response => {
const recent_searches_response = response.data.searches;
const new_recent_searches = [];
recent_searches_response.map(dict => {
new_recent_searches.push(dict.search_term)
})
setRecentSearches(new_recent_searches);
})
.catch((error) => {
console.log("error in getting user profile: ", error.message)
})
}
}, [userId])
useEffect(() => {
const user_profile_api_url = BASE_URL + '/users/' + userId
const request_data = {searches: recentSearches}
axios.post(user_profile_api_url, request_data)
// .then(response => {
// console.log(response)
// })
}, [recentSearches])
const makeSearchApiRequest = () => {
let dividends_api_url = BASE_URL + '/dividends/' + term + '/' + dividendsYearsBack
if (!recentSearches.includes(term)) {
setRecentSearches([...recentSearches, term])
}
axios.get(dividends_api_url, {})
.then(response => {
// console.log(response)
setLoading(false);
setDividendsData(response.data);
})
.catch((error) => {
console.log(error.message);
setLoading(false);
setErrorMessage(error.message);
})
}
const runSearch = () => {
console.log("running search: ", term);
setErrorMessage('');
if (term) {
setLoading(true);
if (!dividendsYearsBack) {
setDividendsYearsBack('3', () => {
makeSearchApiRequest()
});
} else {
makeSearchApiRequest()
}
}
}
const recentSearchOnClick = (term) => {
setTerm(term);
setDebouncedTerm(term);
}
const removeRecentSearchOnClick = (term) => {
const searchesWithoutThisOne = recentSearches.filter(search => search !== term)
setRecentSearches(searchesWithoutThisOne);
}
const dividendsYearsBackOnChange = (text) => {
setDividendsYearsBack(text);
}
const renderMainContent = () => {
if (!debouncedTerm) {
return (
<div className="ui active">
<div className="ui text">Search for info about a stock</div>
</div>
)
}
if (loading === true) {
return (
<div className="ui active dimmer">
<div className="ui big text loader">Loading</div>
</div>
)
}
if (errorMessage) {
return (
<div className="ui active">
<div className="ui text">{errorMessage}</div>
</div>
)
} else {
return (
<DividendResultsDisplay
data={dividendsData}
dividends_years_back={dividendsYearsBack}
dividendsYearsBackOnChange={dividendsYearsBackOnChange}
showMainInfo={showMainInfo}
showYieldChange={showYieldChange}
showAllDividends={showAllDividends}/>
)
}
}
// https://stackoverflow.com/questions/38619981/how-can-i-prevent-event-bubbling-in-nested-react-components-on-click
const renderRecentSearches = () => {
return recentSearches.map((term) => {
return (
<div key={term}>
<button
onClick={() => recentSearchOnClick(term)}
style={{marginRight: '10px'}}
>
<div>{term} </div>
</button>
<button
onClick={(event) => {event.stopPropagation(); removeRecentSearchOnClick(term)}}>
X
</button>
<br/><br/>
</div>
)
})
}
const renderSettingsView = (data) => {
if (settingsViewVisible) {
return (
<SettingsView data={data} />
)
} else {
return null;
}
}
const toggleSettingsView = () => {
setSettingsViewVisible(!settingsViewVisible);
}
const toggleDisplay = (e, setter) => {
setter(e.target.checked)
}
const SETTINGS_DATA = [
{
label: 'Main info',
id: 'main_info',
toggler: toggleDisplay,
setter: setShowMainInfo
},
{
label: 'Yield change',
id: 'yield_change',
toggler: toggleDisplay,
setter: setShowYieldChange
},
{
label: 'Dividends list',
id: 'all_dividends',
toggler: toggleDisplay,
setter: setShowAllDividends
},
]
console.log("showMainInfo: ", showMainInfo);
console.log("showYieldChange: ", showYieldChange);
console.log("showAllDividends: ", showAllDividends);
return (
<div className="ui container" style={{marginTop: '10px'}}>
<SearchBar term={term} onTermUpdate={onTermUpdate} />
{renderRecentSearches()}
<br/><br/>
<button onClick={toggleSettingsView}>Display settings</button>
{renderSettingsView(SETTINGS_DATA)}
<div className="ui segment">
{renderMainContent()}
</div>
</div>
)
}
const mapStateToProps = state => {
return { userId: state.auth.userId };
};
export default connect(
mapStateToProps
)(SearchPage);
// export default SearchPage;
the settingsView component:
import React from 'react';
import SettingsCheckbox from './SettingsCheckbox';
const SettingsView = ({data}) => {
const checkboxes = data.map((checkbox_info) => {
return (
<div key={checkbox_info.id}>
<SettingsCheckbox
id={checkbox_info.id}
label={checkbox_info.label}
toggler={checkbox_info.toggler}
setter={checkbox_info.setter}/>
<br/>
</div>
)
});
return (
<div className="ui segment">
{checkboxes}
</div>
);
}
export default SettingsView;
SettingsCheckbox.js:
import React, {useState} from 'react';
const SettingsCheckbox = ({id, label, toggler, setter}) => {
const [checked, setChecked] = useState(true)
return (
<div style={{width: '200px'}}>
<input
type="checkbox"
checked={checked}
id={id}
name={id}
value={id}
onChange={(e) => {
setChecked(!checked);
toggler(e, setter);
}} />
<label htmlFor="main_info">{label}</label><br/>
</div>
);
}
export default SettingsCheckbox;

How can I get my Note element to update when I change its text?

sorry for the long post, but I'm really stuck in this part of my project. I'm using React to build a notes app, and I can't get my note to update when I alter the text inside of my modal popup...the commented out parts are where I'm having trouble (I wrote what I thought of doing, but don't know how. I've been using React for less than a week). Thank you in advance!
App.js
import React, { useState } from "react";
import { nanoid } from "nanoid";
import NotesList from "./Components/NotesList";
import AddNote from "./Components/AddNote";
const App = () => {
const [notes, setNotes] = useState([
/*empty array of notes*/
]);
const addNote = (title, text) => {
const date = new Date();
const newNote = {
id: nanoid(),
title: title,
text: text,
date: date.toDateString(),
};
const newNotes = [...notes, newNote];
setNotes(newNotes);
};
const deleteNote = (id) => {
const newNotes = notes.filter((note) => note.id !== id);
setNotes(newNotes);
};
const editNote = (text, title, id) => {
const editDate = new Date();
const editedNote = {
id: nanoid(),
title: title,
text: text,
date: editDate.toDateString(),
};
const editedNotes = notes.map((note) => {
if (note.id == id) {
return editedNote;
}
return note;
});
setNotes(editedNotes);
};
return (
<div className="container">
<AddNote handleAddNote={addNote} />
<NotesList
notes={notes}
handleAddNote={addNote}
handleDeleteNote={deleteNote}
editNote={editNote}
updateNote={updateNote}
/>
</div>
);
};
export default App;
NotesList.js
import Note from "./Note";
import React, { useState } from "react";
import MyModal from "./Modal";
const NotesList = ({ notes, handleDeleteNote, updateNote })=> {
const [open, setOpen] = useState(false);
const [note, setNote] = useState({});
const handleOpen = (id) => {
setNote(notes.filter((note) => note.id === id)[0]);
setOpen(true);
};
const handleClose = () => {
setNote({});
setOpen(false);
};
const clickedTodo = useState({});
return (
<div className="notes-list">
<div className="blank-note"></div>
<div className="existing-notes">
<MyModal
note={note}
clickedTodo={clickedTodo}
handleClose={handleClose}
open={open}
updateNote={updateNote}
/>
{notes.map((note) => (
<Note
id={note.id}
title={note.title}
text={note.text}
date={note.date}
handleOpen={handleOpen}
handleDeleteNote={handleDeleteNote}
/>
))}
</div>
</div>
);
};
export default NotesList;
AddNote.js
import { useState } from "react";
import React from "react";
const AddNote = ({ handleAddNote, isUpdate, note, updateNote }) => {
const [noteTitle, setNoteTitle] = useState("");
const [noteText, setNoteText] = useState("");
const characterLimit = 300;
const handleChange = (event) => {
if (characterLimit - event.target.value.length >= 0) {
setNoteText(event.target.value);
}
};
const handleChange2 = (event) => {
if (characterLimit - event.target.value.length >= 0) {
setNoteTitle(event.target.value);
}
};
const handleSaveClick = () => {
// if (!isUpdate) then do this
// if (!isUpdate) {
(noteText.trim().length > 0)
handleAddNote(noteTitle, noteText);
setNoteText("");
setNoteTitle("");
// } else updateNote(note.id)
// else we use all of the info we have gotten
// we call update note with note.id
};
return (
<div className="note new">
<h2>Add note</h2>
<textarea className="new-text-title"
placeholder={!isUpdate?"Add a title...":note.title}
value={noteTitle}
onChange={handleChange2}
></textarea>
<textarea className="new-text-body"
cols="8"
rows="10"
placeholder={!isUpdate?"Type your note here...":note.text}
value={noteText}
onChange={handleChange}
></textarea>
<div className="note-footer">
<small>Characters remaining: {characterLimit - noteText.length}</small>
<button className="save" onClick={handleSaveClick}>
<strong>Save</strong>
</button>
</div>
</div>
);
};
export default AddNote;
Note.js
import { MdDeleteForever } from "react-icons/md";
const Note = (props) => {
const { id, title, text, date, handleOpen, handleDeleteNote } = props;
const handleOpenModal = (id) => {
handleOpen(id);
};
return (
<div className="note">
<div className="note-upper" onClick={() => handleOpenModal(id)}>
<p className="title">
<textarea className="text-title">{title}</textarea>
</p>
<textarea className="text-body">{text}</textarea>
</div>
<div className="note-footer">
<div className="footer-left" onClick={() => handleOpenModal(id)}>
<small>{date}</small>
</div>
<div className="footer-right">
<MdDeleteForever
onClick={() => {
if (window.confirm("Delete this note?")) {
handleDeleteNote(id);
}
}}
className="delete-icon"
size="1.3em"
/>
</div>
</div>
</div>
);
};
export default Note;
Modal.js
import React, { useState } from "react";
import { Modal, Box } from "#mui/material";
import Note from "./Note";
export default function MyModal(props) {
const { open, handleClose, note, updateNote } = props;
return (
<div onClose={console.log("closing")}>
<Modal open={open} onClose={handleClose}>
<Box
sx={{
position: "relative",
top: "50%",
left: "32%",
outline: "none",
}}
>
<Note
updateNote={updateNote}
note={note}
id={note.id}
title={note.title}
text={note.text}
date={note.date}
/>
</Box>
</Modal>
</div>
);
}
Your Modal.js requires updateNote prop, but in App.js you don't supply it to NotesList.js, thus the parent prop of MyModal.js has no such prop:
<NotesList
notes={notes}
handleAddNote={addNote}
handleDeleteNote={deleteNote}
editNote={editNote}
/>
And later in NotesList.js:
<MyModal
note={note}
clickedTodo={clickedTodo}
handleClose={handleClose}
open={open}
updateNote={updateNote} // this is missing because you are not
// passing this prop from the App component
/>

How to replace react component with another when event triggered in that component

So, i (Total react beginner) have this React component.
import './cryptography.css';
import {useRef} from 'react';
import useInterval from 'react-useinterval';
import { useState } from 'react';
const DisplayTimer = () => {
const [time, setTime] = useState(0);
useInterval(() => {
setTime(time + 1);
}
, 1000);
const hours = Math.floor(time / 3600);
const minutes = Math.floor((time % 3600) / 60);
const seconds = time % 60;
return (
<div className="timer">
<h3>Timer</h3>
<p>{hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}</p>
</div>
)
}
const CryptoOne = () => {
const inputRef = useRef();
function verifyAnswer() {
if (inputRef.current.value === "c6e24b99a8054ab24dd0323530b80819") {
alert("Correct!");
}
else {
alert("Wrong!");
}
}
return (
<div className="crypto-one">
<h3>Level One</h3>
<p>Convert this plaintext into an MD5 hash - "RollingStonesGatherNoMoss"</p>
<input ref={inputRef} type="text" id="one-answer" name="one-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
)
}
const CryptoTwo = () => {
const inputRef = useRef();
function verifyAnswer() {
if (inputRef.current.value === "IaMaHackerManHaHa") {
alert("Correct!");
}
else {
alert("Wrong!");
}
}
return (
<div className="crypto-two">
<h3>Level Two</h3>
<p>Decode Caesar cipher into plaintext - "FxJxExzhboJxkExEx"</p>
<input ref={inputRef} type="text" id="two-answer" name="two-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
)
}
const CryptoThree = () => {
const inputRef = useRef();
function verifyAnswer() {
let input = inputRef.current.value;
let answer = "SHA256".toLowerCase();
if (input === answer) {
alert("Correct!, completed the exercise");
}
else {
alert("Wrong!");
}
}
return (
<div className="crypto-three">
<h3>Level Three</h3>
<p>Identify the type of the hash (Type only the hash type, with no spaces) - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"</p>
<input ref={inputRef} type="text" id="three-answer" name="three-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
)
}
const Cryptography = () => {
const [active, setActive] = useState("crypto-one");
return (
<div className="cryptography">
<h1>Cryptography</h1>
<DisplayTimer />
<div className="crypto-container">
<CryptoOne />
</div>
</div>
)
}
export { Cryptography };
Here, i have this cryptography function that will display a question and if it is correct, that question will be replaced with another.
I have 3 seperate functions CryptoOne, CryptoTwo and CryptoThree which will be displayed in function Cryptography. So that means if the answer for the question for CryptoOne is correct, then it will be replaced with CryptoTwo and so on. So my questions is HOW DO I DO IT?
Thanks in advance.
ANSWER TO YOUR LAST COMMENT TO HANDLE TIMER
Instead of using react-useinterval you could create a useTimer() hook of your own
import { useEffect, useRef, useState } from "react";
const useTimer = () => {
const [time, setTime] = useState(0);
const hours = Math.floor(time / 3600);
const minutes = Math.floor((time % 3600) / 60);
const seconds = time % 60;
let interval = useRef();
useEffect(() => {
interval.current = setInterval(() => {
setTime(prevTime => prevTime + 1);
}, 1000);
return () => {
clearInterval(interval.current);
};
}, [setTime]);
const stopTimer = () => {
clearInterval(interval.current);
};
return { hours, minutes, seconds, stopTimer };
};
export default useTimer;
You can maintain a activeIndex state in Cryptography component. And have a changeSlide method which increments activeSlideIndex by 1 everytime the answer is correct. As shown below
TIMER RELATED COMMENT
Use that hook in Cryptography component. Pass hours, minutes & seconds as props in DisplayTimer component. And pass stopTimer function to CryptoThree component & use it when final answer is complete
const Cryptography = () => {
const [active, setActive] = useState("crypto-one");
const [activeIndex, setActiveIndex] = useState(1);
const { hours, minutes, seconds, stopTimer } = useTimer();
const incrementIndex = () => {
setActiveIndex(prevIndex => prevIndex + 1);
};
return (
<div className="cryptography">
<h1>Cryptography</h1>
<DisplayTimer hours={hours} minutes={minutes} seconds={seconds} />
<div className="crypto-container">
{activeSlideIndex === 1 && <CryptoOne changeIndex={incrementIndex} />}
{activeSlideIndex === 2 && <CryptoTwo changeIndex={incrementIndex} />}
{activeSlideIndex === 3 && <CryptoThree stopTimer={stopTimer} />}
</div>
</div>
);
};
const DisplayTimer = ({ hours, minutes, seconds }) => {
return (
<div className="timer">
<h3>Timer</h3>
<p>
{hours.toString().padStart(2, "0")}:
{minutes.toString().padStart(2, "0")}:
{seconds.toString().padStart(2, "0")}
</p>
</div>
);
};
You can pass this changeSlide() method as a prop in every component.
And call it whenever the answer is correct
const CryptoOne = ({ changeIndex }) => {
const inputRef = useRef();
function verifyAnswer() {
if (inputRef.current.value === "c6e24b99a8054ab24dd0323530b80819") {
alert("Correct!");
changeIndex();
} else {
alert("Wrong!");
}
}
return (
<div className="crypto-one">
<h3>Level One</h3>
<p>
Convert this plaintext into an MD5 hash - "RollingStonesGatherNoMoss"
</p>
<input ref={inputRef} type="text" id="one-answer" name="one-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
);
};
const CryptoTwo = ({ changeIndex }) => {
const inputRef = useRef();
function verifyAnswer() {
if (inputRef.current.value === "IaMaHackerManHaHa") {
alert("Correct!");
changeIndex();
} else {
alert("Wrong!");
}
}
return (
<div className="crypto-two">
<h3>Level Two</h3>
<p>Decode Caesar cipher into plaintext - "FxJxExzhboJxkExEx"</p>
<input ref={inputRef} type="text" id="two-answer" name="two-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
);
};
const CryptoThree = ({stopTimer) => {
const inputRef = useRef();
function verifyAnswer() {
let input = inputRef.current.value;
let answer = "SHA256".toLowerCase();
if (input === answer) {
alert("Correct!, completed the exercise");
stopTimer(); // Use stopTimer here when exercise is complete
} else {
alert("Wrong!");
}
}
return (
<div className="crypto-three">
<h3>Level Three</h3>
<p>
Identify the type of the hash (Type only the hash type, with no spaces)
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
</p>
<input ref={inputRef} type="text" id="three-answer" name="three-answer" />
<button onClick={verifyAnswer}>Submit</button>
</div>
);
};

How can I display the results of a function in React?

I would like to display in a paragraph tag the results of a function after an input. This is what I have tried:
import React, { useState } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button>Show</button>
<p>{checkLumens()}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;
Thanks for the help!
Create a state to show and hide the lumens value using useState, and change the value on button click
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [showLumens, setShowLumnes] = useState(false);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={()=>setShowLumnes(true)}>Show</button>
{showLumens && <p>{checkLumens()}</p>}
</div>
);
};
export default Measurement;
Just add a new state variable:
import React, { useState } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [showLumens, setShowLumens] = useState(false);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={() => setShowLumens(true)}>Show</button>
<p>{showLumens ? checkLumens() : null}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;
import React, { useState, useEffect } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [lumens, setLumens] = useState('Not Set')
const [show, setShow] = useState(false)
useEffect(() => {
if (brightness > 120) {
setLumens("High");
}
if (darkness < 80) {
setLumens("Low");
}
else {
setLumens("Not Set");
}
}, [darkness, brightness])
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={() => setShow(true)}>Show</button>
<p>{show && lumens}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;

Categories

Resources