I'm trying to implement a transition effect in my custom toast. I'm using react-transition-group and react-reveal to do it. The documentation seems very simple and i just followed this steps https://www.react-reveal.com/examples/advanced/todo/
The problem is that it is olny working when the toast is closing. It dosn`t work when appear.
import Toast from ".";
import { useContext } from "react"
import { ToastStateContext } from "./context";
import { TransitionGroup } from "react-transition-group";
import Fade from 'react-reveal/Fade';
export default function ToastContainer() {
const { toasts } = useContext(ToastStateContext);
return (
<>
{toasts && (
<div className="absolute top-24 pt-1 right-2">
<TransitionGroup enter exit>
{
toasts.map((toast) => {
return (
<Fade key={toast.id} top>
<Toast
id={toast.id}
key={toast.id}
type={toast.type}
message={toast.message}
/>
</Fade>
)
})
}
</TransitionGroup>
</div>
)}
</>
);
}
Related
Small premise: I'm not a great Typescript expert
Hi everyone, I'm working on my personal site, I decided to develop it in Typescript to learn the language.
My component tree is composed, as usual, of App.tsx which render the sub-components, in this case Navbar.jsx and Home.jsx.
Below is the App.jsx code:
import './App.css';
import { BrowserRouter as Router, useRoutes } from 'react-router-dom';
import Home from './components/Home';
import Navbar from './components/Navbar';
import { useState } from 'react';
function App(){
const [navbarScroll,setNavbarScrool]=useState(Object)
const handleLocationChange = (navbarScroll : boolean) => {
setNavbarScrool(navbarScroll)
return navbarScroll
}
const AppRoutes = () => {
let routes = useRoutes([
{ path: "/", element: <Home handleLocationChange={handleLocationChange}/> },
{ path: "component2", element: <></> },
]);
return routes;
};
return (
<Router>
<Navbar navbarScroll={navbarScroll}/>
<AppRoutes/>
</Router>
);
}
export default App;
Here, instead, the Home.jsx code:
import { useInView } from 'react-intersection-observer';
import HomeCSS from "../styles/home.module.css"
import mePhoto from "../assets/me.png"
import { useEffect, useState } from 'react';
interface AppProps {
handleLocationChange: (values: any) => boolean;
}
export default function Home(props: AppProps){
const { ref: containerChange , inView: containerChangeIsVisible, entry} = useInView();
useEffect(()=>{
props.handleLocationChange(containerChangeIsVisible)
//returns false at first render as expected
console.log("Home "+containerChangeIsVisible)
},[])
return(
<>
<div className={`${ HomeCSS.container} ${containerChangeIsVisible? HomeCSS.container_variation: ''}`}>
<div className={HomeCSS.container__children}>
{/* when i scroll on the div the css change (this works)*/}
<h1 className={`${ HomeCSS.container__h1} ${containerChangeIsVisible? HomeCSS.container__h1_variation: ''}`}>My<br/> Name</h1>
<p>Computer Science student.</p>
</div>
<img src={mePhoto} className={HomeCSS.image_style}/>
</div>
<div ref={containerChange} style={{height:800,background:"orange"}}>
<p style={{marginTop:20}}>HIII</p>
</div>
</>
)
}
And Navbar.jsx:
import NavbarCSS from "../styles/navbar.module.css"
import acPhoto from "../assets/ac.png"
import { Link } from "react-router-dom";
import { useEffect, useState } from "react";
interface NavbarScroolProp{
navbarScroll:boolean
}
export default function Navbar(props:NavbarScroolProp){
const [scrollState,setScrollState]=useState(false)
const [pVisible,setpVisible] = useState('')
useEffect(()=>{
setTimeout(() => {
setpVisible("")
}, 3000)
setpVisible("100%")
},[])
//returns false also when should be true
console.log(props.navbarScroll)
return (
<>
{/*the props is undefined so the css doesn't change, i need to do this*/}
<nav className={`${props.navbarScroll?NavbarCSS.nav__variation:NavbarCSS.nav}`}>
<div className={NavbarCSS.nav_row}>
<div className={NavbarCSS.nav_row_container}>
<img src={acPhoto} className={NavbarCSS.image_style}/>
<p className={NavbarCSS.p_style} style={{maxWidth: pVisible}}>My name</p>
</div>
<div className={NavbarCSS.nav_row_tagcontainer}>
<Link className={NavbarCSS.nav_row_tag} to="/"> Home</Link>
<Link className={NavbarCSS.nav_row_tag} to="/"> About</Link>
<Link className={NavbarCSS.nav_row_tag} to="/"> Contact</Link>
</div>
</div>
</nav>
</>
);
}
In my application I want to change the background color whenever the div referring to the InsertionObserver ( I use "useInView" hook , from :https://github.com/thebuilder/react-intersection-observer) is displayed. The problem is that the div in question is in the Home.jsx component and I need to change the color of the divs in the navbar as well when the div in Home is triggered(or other components in case I need to in the future).
The question is: How can I dynamically trigger DOM elements of other components (to then perform certain operations) using the InsertionObserver ?
As you can see from the code I tried to create Props, but everything returns undefined and doesn't involve any changes.
I've tried without useEffect, without using the useInView hook, passing the object instead of the boolean value, but I can't find any solutions to this problem.
You would be of great help to me.
PS: I would like to leave the Navbar.jsx component where it is now, so that it is visible in all components.
Any advice or constructive criticism is welcome.
I have a simple react page so far where I just have a home component which seems to work fine it is made up from the code I have included what I am trying to do is to render another component the main component when the button that is part of the home component is clicked but it keeps giving me the error and I have no idea what I am doing wrong in this case I have included code for all of my files the main component isn't fully finished right now it was just to test what I am currently doing that I added a paragraph placeholder any help is appreciated thanks
Error: Unknown error
(/node_modules/react-dom/cjs/react-dom.development.js:3994) !The above
error occurred in the component: at Main (exe1.bundle.js:94:3)
at div at App (exe1.bundle.js:31:52) Consider adding an error boundary
to your tree to customize error handling behavior. Visit
https://reactjs.org/link/error-boundaries to learn more about error
boundaries. !Error: Unknown error
Home Component:
import React from "react";
export default function Home(props) {
return (
<main className="home-main">
<div className="content-container">
<div className="bottom-corner">
</div>
<div className="top-corner">
</div>
<h1 className="home-heading">Quizzical</h1>
<p className="home-description">Some description if needed</p>
<button
className="start-button"
onClick={props.handleClick}
>Start quiz
</button>
</div>
</main>
)
}
Main Component:
import react from "react";
export default function Main() {
return (
<h1>hello </h1>
)
}
App:
import React from "react";
import Main from "./components/Main"
import Home from "./components/Home"
export default function App() {
const [startQuiz, setStartQuiz] = React.useState(false);
function clickStart() {
// flip the state on each click of the button
console.log(startQuiz);
setStartQuiz(prevState => !prevState);
}
return (
<div>
{console.log("start", startQuiz)}
{startQuiz ?
<Main />
:
<Home handleClick={clickStart}/> }
}
</div>
)
}
Index:
import React from "react"
import ReactDOM from "react-dom"
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"))
I think you just have a typo here
import react from "react";
should be
import React from "react";
You can try changing your setStartQuiz to just simply negate the current startQuiz value instead of using prevState.
function clickStart() {
// flip the state on each click of the button
console.log(startQuiz);
setStartQuiz(!startQuiz);
}
Here's a working example based on your code.
code sandbox
import React, { useState } from "react";
const Main = () => <h1>hello </h1>;
const Home = (props) => {
return (
<main className="home-main">
<div className="content-container">
<div className="bottom-corner"></div>
<div className="top-corner"></div>
<h1 className="home-heading">Quizzical</h1>
<p className="home-description">Some description if needed</p>
<button className="start-button" onClick={props.handleClick}>
Start quiz
</button>
</div>
</main>
);
};
export default function App() {
const [startQuiz, setStartQuiz] = useState(false);
return (
<div>
{startQuiz && <Main />}
{!startQuiz && <Home handleClick={() => setStartQuiz(true)} />}
</div>
);
}
I am trying to change the orientation of the MATH formula between horizontal and vertical orientation using react hooks.
How can I make the formula change its orientation every time I click the button? - (from horizontal to vertical and vice versa)
I have tried this code but it doesn't work. (I am new to react)
This is App.js
import './App.css';
import Horizontal from './horizontal';
import Vertical from './vertical';
import { useState} from 'react'
function App() {
const [orientation, setOrientation] = useState(<Vertical/>)
const clickOrientation = () => {
if (orientation===<Horizontal/>){
setOrientation(<Vertical/>)
}
else if (orientation === <Vertical />) {
setOrientation(<Horizontal/>)
}}
console.log(orientation)
return (
<div className='App'>
{orientation}
<button onClick={clickOrientation}>change orientation</button>
</div>
)
}
export default App;
This is horizontal.jsx
import React from 'react'
function Horizontal() {
return (
<div>
1 + 2
</div>
)
}
export default Horizontal
This is vertical.jsx
import React from 'react'
function Vertical() {
return (
<div>
1
+
2
</div>
)
}
export default Vertical
In your case checking whether value is equals to a component will not work as expected. Therefore the best way to use your code is define a boolean or string with useState and use conditional rendering inside the return.
You can try one of the following methods.
Method 1 (useState with string)
import './App.css';
import Horizontal from './horizontal';
import Vertical from './vertical';
import { useState} from 'react'
function App() {
const [orientation, setOrientation] = useState('vertical')
const clickOrientation = () => {
if (orientation==='vertical'){
setOrientation('horizontal');
}
else if (orientation === 'horizontal') {
setOrientation('vertical');
}
}
return (
<div className='App'>
{
orientation === 'vertical' ? (<Vertical />) : (<Horizontal />)
}
<button onClick={clickOrientation}>change orientation</button>
</div>
)
}
export default App;
Method 2 (useState with boolean)
import './App.css';
import Horizontal from './horizontal';
import Vertical from './vertical';
import { useState} from 'react'
function App() {
const [isVertical, setIsVertical] = useState(true)
const clickOrientation = () => {
if (isVertical){
setIsVertical(false);
} else {
setIsVertical(true);
}
}
return (
<div className='App'>
{
isVertical ? (<Vertical />) : (<Horizontal />)
}
<button onClick={clickOrientation}>change orientation</button>
</div>
)
}
export default App;
Note: Further consider about how to align items inside two components. In vertical component it's better to have <br /> at the end of each line to break lines.
You can add <br/> tag to make it vertical
function Vertical() {
return (
<div>
1 <br/> + <br/> 2
</div>
)
}
or separate them by div tag
function Vertical() {
return (
<>
<div>1</div>
<div>+</div>
<div>2</div>
</>
)
}
You need to use conditional-rendering to render Vertical or Horizontal. You can read mỏe in: https://reactjs.org/docs/conditional-rendering.html
I am trying to create a custom hook to be able to open and close a pop-out menu with conditional rendering using style display: none and display:block. I think I understand how to share the state between the components (I can console log that and get that working) , but I can not figure out how to update the state using the hook.
I am certain that I have some fundamental misunderstanding here but if anyone can clarify what it is I am trying to achieve that would be awesome! I have tried to learn this for several nights and here is where I have got to.
This is the header of the pop out menu it only contains a close button at the moment
import React from 'react'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faWindowClose } from '#fortawesome/free-solid-svg-icons'
import useOpenCloseElementMenu from '../Hooks/openCloseElementMenu'
function ElementMenuHeader() {
const { elementMenuOpenClose, setElementMenuOpenClose } = useOpenCloseElementMenu();
return (
<div id="App-Close-Element-Menu-Container">
<button id="App-Close-Element-Menu"
onClick={() => setElementMenuOpenClose(false) }
>
<FontAwesomeIcon icon={faWindowClose} />
</button>
</div>
);
}
export default ElementMenuHeader
This is the pop out menu
import React from 'react';
import SizerGroup from '../Sizer/sizerGroup';
import './element-menu.css';
import ElementMenuHeader from './element-menu-header';
import TitleWithLine from './title-with-line';
import TypeSelector from './type-selector';
import TemplateSelector from './template-selector';
import useOpenCloseElementMenu from '../Hooks/openCloseElementMenu'
function Editor(props) {
const { elementMenuOpenClose, setElementMenuOpenClose } = useOpenCloseElementMenu();
console.log(elementMenuOpenClose);
return (
<div className="App-Element-Menu"
style={{display: elementMenuOpenClose ? 'block' : 'none' }}
>
<ElementMenuHeader />
<TitleWithLine title="Element size" />
<SizerGroup />
<TitleWithLine title="Elements" />
<TypeSelector />
<TitleWithLine title="Templates" />
<TemplateSelector />
</div>
);
}
export default Editor
This is the toolbar that has the open menu button
import React from 'react'
import Button from '../Button/button'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faBoxes } from '#fortawesome/free-solid-svg-icons'
import './toolbar.css'
import useOpenCloseElementMenu from '../Hooks/openCloseElementMenu'
function Toolbar(props) {
const { toolbar_show_or_hide } = props
const elementMenuIcon = <FontAwesomeIcon icon={ faBoxes } />
const { elementMenuOpenClose, setElementMenuOpenClose } = useOpenCloseElementMenu();
const openEditor = setElementMenuOpenClose[true]
return (
<div className="App-Toolbar" style={{ display: toolbar_show_or_hide ? "flex" : "none" }} >
<Button
id="App-Open-Element-Menu-Button"
icon={ elementMenuIcon }
useToolTip={ true }
toolTipText="Elements menu. Select elements to populate the theme."
buttonFunction={ openEditor }
/>
</div>
)
}
export default Toolbar
This is the hook
import React, { useState } from 'react';
const useOpenCloseElementMenu = () => {
const [elementMenuOpenClose, setElementMenuOpenClose] = useState(false);
return { elementMenuOpenClose, setElementMenuOpenClose };
};
export default useOpenCloseElementMenu;
I feel you donot have to pass the hook in a separate function, useOpenCloseElementMenu, like you did.
Instead of importing the ../Hooks/openCloseElementMenu function thing,
I'd rather just call the hooks directly instead as
const [elementMenuOpenClose, setElementMenuOpenClose] = useState(false);
in the editor and toolbar component in place of const { elementMenuOpenClose, setElementMenuOpenClose } = useOpenCloseElementMenu();.
Also which component did you use the toolbar component if I may ask? Because I don't seem to see any of that here...It confusing where it got the toolbar_show... props from.
{I hope this helps cause that seem like the most obvious reason}
Context
I created a Context and exported both Producer and Consumer. I am now wrapping my app level example with Producer. I want to be able to consume ContextConsumer inside a module which is served by a different package.
However, when I try to use ContextConsumer inside such module, it throws out the error, cannot call function of undefined.
Code Structure
The below is how I have my code structured.
Context-v1 package
Context.js
import React, { Component, createContext } from 'react';
import PropTypes from 'prop-types';
import ZIndexUtils from './zIndexUtils';
const { node } = PropTypes;
const { Provider, Consumer: IDSContextConsumer } = createContext();
class IDSContextProvider extends Component {
static propTypes = {
children: node.isRequired
};
state = {
topZIndex: ZIndexUtils.getTopZIndex(),
incrementTopZIndex: ZIndexUtils.incrementTopZIndex
};
render() {
return (
<Provider
value={{
topZIndex: this.state.topZIndex,
incrementTopZIndex: this.state.incrementTopZIndex
}}
>
{this.props.children}
</Provider>
);
}
}
export { IDSContextProvider };
export default IDSContextConsumer;
index.js
import IDSContextConsumer, { IDSContextProvider } from './Context';
export {
IDSContextProvider,
IDSContextConsumer
};
Dropdown-v1 package
This component makes use of another component called as Menu-v1 which is where I am trying to use Consumer to access the increment function that I am passing down from app level example.
import { IDSContextConsumer } from '#ids/context-v1';
...
...
render() {
return (
<IDSContextConsumer>
{
(context) => (
<ZIndex assignZIndex getTopZindex={context.incrementTopZIndex}>
<MenuList
className={className}
autoFocus={autoFocus}
aria-label={this.props['aria-label']}
onKeyDown={this.handleKeyDown}
onBlur={this.handleMenuBlur}
reference={reference}
ref={refReactDom}
style={style}
>
{items}
</MenuList>
</ZIndex>
)
}
</IDSContextConsumer>
)
}
App example
Finally, I am trying to use this Dropdown module into my app. Which is where I expect to see the incrementer function be passed in via context.
import { IDSContextProvider } from '#ids/context-v1';
import { Dropdown, MenuItem } from '#ids/dropdown';
render() {
return (
<div>
<IDSContextProvider>
<Modal
open={this.state.openModalDialog}
onCloseModalDialog={this.handleModalClosing}
title="Modal with Dropdown"
>
<Dropdown
onBlur={() => console.log('Dropdown blurrrrr')}
label="Name"
value={this.state.value}
onChange={this.handleDropdownChange}
>
<MenuItem value="1">Banana</MenuItem>
<MenuItem value="2">Apple</MenuItem>
<MenuItem value="3">Guava</MenuItem>
<MenuItem value="4">Mango</MenuItem>
</Dropdown>
</Modal>
</IDSContextProvider>
<button className="divRenderButton" onClick={this.handleModalOpening}>Open Modal</button>
</div>
);
}
Modal component in my example
<Portal>
<Transition
enterClassName={`${prefix}--slideIn`}
transition={open ? transitions.enter : transitions.exit}
onEntered={onShow}
onExited={onClose}
exitClassName={`${prefix}--slideOut`}
unmountOnExit
>
<IDSContextConsumer>
{
(context) => (
<ZIndex
assignZIndex={open}
underlay
getTopZindex={context.incrementTopZIndex}
>
<div
className={open ? 'divContainerWithUnderlay' : ''}
>
{
open &&
<div>
<h1 className="divContent">{title}</h1>
{
this.props.children ? this.props.children : null
}
<button className="divRenderButton" onClick={this.closeModalDialog}>Close Modal</button>
</div>
}
</div>
</ZIndex>
)
}
</IDSContextConsumer>
</Transition>
</Portal>
Requesting earnest help on this. I have tried the solutions from this forum before and cannot find any approach where the modules from different packages share the context.