Render component on button click to change page view with useState (or otherwise) in React - reactjs

I've made a landing page for my portfolio and I'd like to have the page perform a transition animation (like a fadeout/In, but I can get to that later) then render the component of my actual portfolio instead of my landing page on the button click.
I started trying to write a function but am a bit lost with how to implement this.
I have this as my App setup so far but can't figure out how to implement the state change to render the Portfolio component instead of the HTML from App.js
import React, { useState } from "react";
import "./App.css";
// import Portfolio from "./Portfolio"
function App() {
//States
// const [view, setView] = useState();
// function viewPortfolio (
// )
return (
<div className="App">
<div className="title">
<h1 className="title maintext">Josh Bellingham</h1>
<h2 className="title subtext">Junior Web Developer</h2>
<button className="title btn">
<span>Welcome</span>
</button>
</div>
<div className="sun">
<img className="sun-img" src="Sun.png" alt="Sun" />
<div className="sun-ray r-one"></div>
<div className="sun-ray r-two"></div>
<div className="sun-ray r-three"></div>
<div className="sun-ray r-four"></div>
</div>
<div className="waves">
<img className="wave-1" src="Wave 1 (1).png" alt="Wave"></img>
<img className="wave-2" src="Wave 2 (1).png" alt="Wave"></img>
<img className="wave-3" src="Wave 3 (1).png" alt="Wave"></img>
</div>
</div>
);
}

just define a function in your code and call it with arrow functions or you can use the bind function. ps, it is good to use 'useMemo' or 'useCallback' hooks depending on your
function App() {
const [count, setCount] = useState(0);
//define function
const testFunction = () => {
console.log("you can call a function here ");
setCount(10); // or whatever you want to call
}
return (
<div className="App">
{/* call function */}
<button onClick={() => testFunction()}>test btn</button>
<p>{count}</p>
</div>
)
}
you can call any function with onClick method. if you just pass the function to the onClick, it will call your function when the component is being rendered and we don't want that for now, we wrap that in the arrow-function. every time you call a function and it changes any state in your component, it will cause re-rendering, so if you want to re-render you should change some states.
in the code I wrote when you click on the test btn you call testFunction and it will change the count state to 10 and it will cause re-rendering, we can use that state as I used it in the paragraph
you can read more at events or hooks ,lifecycle

Related

Can someone tell me why my app crashes when I refresh the page?

I added a weather component in my app that fetches weather from open weather map. It works fine until I refresh the page, then it breaks.
If I comment the weather component out when refreshing and then add it back in when loaded it renders and works.
I'm not sure what's causing this error.
Here's some images of the console after refreshing for reference.
It seems to be undefined when refreshed. What's causing this issue?
// Weather component is called as normal in Home page
<div className="main-section-one">
<Weather />
<ToDoWidget />
</div>
import React, { useEffect, useState } from 'react'
//CSS
import '../css/Weather.css'
function Weather() {
// API
const URL = 'https://api.openweathermap.org/data/2.5/weather?q=barcelona&appid=APIKEY';
// State
const [weatherDetails, setWeatherDetails] = useState({});
async function getWeather() {
let fetchUrl = await fetch('https://api.openweathermap.org/data/2.5/weather?q=barcelona&appid=APIKEY&units=metric');
let data = await fetchUrl.json()
setWeatherDetails(data)
}
//Use Effect
useEffect(() => {
getWeather();
}, [])
return (
<div className="weather-container">
<div className="weather-one">
<div className="city">
<h3>Barcelona</h3>
<h1 className='temp'>{weatherDetails.main.temp}°C</h1>
</div>
<div className="current-weather">
<h3 className='current'>Sunny</h3>
</div>
</div>
<div className="weather-two">
<div className="">
<p>{weatherDetails.main.feels_like}°C</p>
<p className='weather-details'>Feels Like</p>
</div>
<div className="">
<p>{weatherDetails.main.humidity}%</p>
<p className='weather-details'>Humidity</p>
</div>
<div className="">
<p>{weatherDetails.wind.speed} MPH</p>
<p className='weather-details'>Wind Speed</p>
</div>
</div>
</div>
)
}
export default Weather
The main and wind properties may be undefined. Secure it.
<h1 className='temp'>{weatherDetails.main?.temp}°C</h1>
^^^ optional chaining
<p>{weatherDetails.wind?.speed} MPH</p>
Reference: Optional chaining

How can i unmount a functional component from DOM on click of a Button

I would like to "Unmount a simple Functional Component" from the DOM. I searched a lot and saw most of the tutorials are based on Class Components and I did'nt see any simple example on it. My requirement is Unmounting a Functional component from the DOM on click on a button. Following is the component with the button which i likes to unmount when click on it. Hopes someone can help me to do it. Thanks in Advance !
import React from 'react'
function App() {
return (
<div className='app-component'>
<h2 className="h2">App Component</h2>
<button>Unmount This Component</button>
</div>
)
}
export default App
If you want to unmount a component then you can use conditional rendering where you can declare state in parent component and based on the state you can mount or unmount component as:
This is the parent component from where you want to mount or unmount
CODESANDBOX DEMO
If you want to toggle component once then you can do the following because there is only one way to change state i.e from Test component. If you unmount this component there is no way to mount it again. So you can also declare button in App component from where you can mount or unmount on click of a button. CODESANDBOX
Parent component
export default function App() {
const [isShowing, setIsShowing] = useState(true); // STATE
return (
<div className="App">
{isShowing && <Test setIsShowing={setIsShowing} />}
</div>
);
}
Child component
function Test({ setIsShowing }) {
function unmountComponent() {
setIsShowing(false);
}
return (
<div className="app-component">
<h2 className="h2">App Component</h2>
<button onClick={unmountComponent}>Unmount This Component</button>
</div>
);
}
You can use state flag for removing element like this:
import React from 'react'
function App() {
const [flag,setFlage]=useState(true);
return (
<div className='app-component'>
{flag?<h2 className="h2">App Component</h2>:null}
<button onClick={()=>setFlag(!flage)} >Unmount This Component</button>
</div>
)
}
export default App

How do i use useEffect() / useState() hooks here

I am new to React Js and learning to implement certain functionalities by developing a website. Here i need to implement something like this -
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_typewriter but on page load (not on button click)
But as we know that React has Hooks, which needs to be used while implementing functionalities in the project. So i tried to implement Hook, but need some help in using it, I researched some examples on internet but didn't understood and doesn't fit for my current requirement.
Main.js
import React, { useEffect } from 'react';
import '../App.css';
const Main = () => {
useEffect( () => {
var i = 0;
var txt = 'Some Text here lorem ipsum lorem ipsum';
var speed = 50;
function typeWriter() {
if (i < txt.length) {
document.getElementById("typingText").innerHTML += txt.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
}
});
return(
<main>
<div className='row'>
<img src='image.png' height='auto' width='100%' alt="banner"/>
<div className='position-absolute top-50 start-0 translate-middle-y p-5'>
<div class="card bg-black" style={{width: '30%'}}>
<div class="card-body text-white fw-bold">
<h1 id="typingText"></h1>
</div>
</div>
</div>
</div>
</main>
);
export default Main;
First of all, you are missing the array of dependencies of the hook. This prop is extemely important, otherwise the useEffect hook will keep on calling, reaching an overflow of calls.
If I understand what you want, every x milliseconds the typed text should change. useEffect will do the work. In this case, as you want only to run when the component mounts, the dependency array of the hook will be empty ([]). Inside the hook, you can set up an interval, that keeps running the function that you want. With this brief explanation, you could do:
import React, { useEffect, useState } from 'react';
import '../App.css';
const Main = () => {
// We will keep track of how many letters are being displayed
const [index, setIndex] = useState(0);
const type = () => {
setIndex((prev) => Math.min(prev + 1, 50));
};
useEffect(() => {
const id = setInterval(type, 500);
// It is important to clear the interval when the component unmounts!
return () => clearInterval(id);
}, []); // We are setting an empty dep array
return (
<main>
<div className='row'>
<img src='image.png' height='auto' width='100%' alt='banner' />
<div className='position-absolute top-50 start-0 translate-middle-y p-5'>
<div class='card bg-black' style={{ width: '30%' }}>
<div class='card-body text-white fw-bold'>
<h1 id='typingText'>
{'Your text'.substring(0, index)}
</h1>
</div>
</div>
</div>
</div>
</main>
);
};
export default Main;
To sum up, what we are doing is:
Setting an interval to repeat after 500ms. As commented in the code, it is crucial to clear the interval once the component unmounts. The setInterval returns the identifier of the interval, which is used to identify the interval to remove with clearInterval.
Instead of using the window to manipulate the DOM, we keep track of the state, increasing the letters to display from our string.
Finally, we "cut" the string displaying from 0 to the current index, which will be incremented every 500ms, creating the typewritter effect.
Hope to have been clear!
I recommend you take a look at the react hooks documentation.

Div content is mapping different components

I want to ask how could I implement in reactjs the next thing.
Imagine a page with 2 buttons and a div. When I press one button the content of the div would be a list of components mapped. When I press the other button the div content would be another list of components ( different component type as well ).
So more or less, the effect that results from this is a menu inside a page that loads different things in a div.
I am also willing to hear other options of implementing this, but mostly i'm here to ask you for a short example of how could I implement this thing.
import { useState } from "react";
import "./styles.css";
const Component1 = () =>{
return(
<div>
<h1>Component 1</h1>
</div>
)
}
const Component2 = () =>{
return(
<div>
<h1>Component 2</h1>
</div>
)
}
export default function App() {
const [component, setComponent] = useState("COMPONENT_1");
const renderComponent = () =>{
switch(component){
case "COMPONENT_1":
return <Component1/>
case "COMPONENT_2":
return <Component2/>
default:
return <div/>
}
}
return (
<div className="App">
<div>
{renderComponent()}
</div>
<button onClick={()=>setComponent("COMPONENT_1")}>Render component 1</button>
<button onClick={()=>setComponent("COMPONENT_2")}>Render component 2</button>
</div>
);
}
you can replace Component1 and Component2 with whatever you want.
Or
You can use a library like React Router https://reactrouter.com/
let me know if there is anything else you want me to add.

How to toggle class of a div element by clicking on a button that is inside another functional component (another file)?

I want to toggle class of container (file 2) by an onClick on the button that is inside another component file.
The button has already an onClick function and I want to make it so it calls on two functions. Two toggle functions for the button and two class toggles for the container.
Hope it makes sense.
Here is my code so far:
Button component (File 1)
import React, {useState} from "react";
import "./Sort.scss";
const Sort = () => {
const [toggleSortIcon, toggleSortIconSet] = useState(false);
return (
<div className="tools">
<button
onClick={() => toggleSortIconSet(!toggleSortIcon)}
className={`sort ${toggleSortIcon ? "horizontal" : "vertical"}`}>
</button>
</div>
);
}
export default Sort;
Div container component that I want to change the class of (File 2)
import React, {useState} from "react";
import "./WordContainer.scss";
import UseAnimations from "react-useanimations";
const WordContainer = ({title, definition, example}) => {
const [toggleSize, toggleSizeState] = useState(false);
return (
<div className={`container ${toggleSize ? "big" : "small"}`}>
<div className="content">
<h2>{title}</h2>
<p>{definition}</p>
<h3>Example</h3>
<p>{example}</p>
</div>
<img onClick={() => toggleSizeState(!toggleSize)} src="./resize.svg" alt="resize" className="resize"/>
<div className="bookmark">
<UseAnimations
animationKey="bookmark"
size={26}
/>
</div>
</div>
);
}
export default WordContainer;
You could either have a global state management system (redux, or with custom hooks) that you can use to store the icon size.
Or you could simply provide a callback to your component that stores the icon size in a parent component that then feeds it back to your
Something like this:
const [size, setSize] = useState(/* default value */);
render() {
<>
<Sort onSizeToggle={setSize} />
<WordContainer size={size} />
</>
}

Resources