Getting compile error from React Component useState - reactjs

This is the code of the component:
import React, {useState, useEffect} from 'react'
import NavBar from './Navbar'
import axios from 'axios'
import {Link, useHistory} from 'react-router-dom'
function mygroups() {
let profile_id = localStorage.getItem('profile_id')
const [group, setgroup]=useState([])
useEffect(()=>{
axios.get(`/getgroups?profile_id=${profile_id}`)
.then(res=>setgroup(res.data))
.then(res=>{
//localStorage.setItem("screen_name",res.data.screenname)
//localStorage.setItem("profile_id",res.data._id)
})
.catch(err=>console.log(err))
})
return (
<div>
<NavBar />
<h3 className='bg-primary p-2 text-center'>Groups</h3>
{
group.map((data,key)=>(
<div className='container'>
<h2>{data.name}</h2>
<span className='badge badge-dart p-2'>{data.name}</span>
<h6 className='text-white mt-4'>{data.no_members}</h6>
<hr style={{border:'1pz dotted white'}} />
</div>
))
}
</div>
)
}
export default mygroups
This was based off from another component that works perfectly fine. I just changed the variable names. Even when I comment out all of the code and just have the const [group, setgroup]=useState([]), I get this compile error right away. Any help is greatly appreciated. Thanks.

You need to tell React that mygroups is a functional component rather than a regular function, otherwise it won't permit you to use hooks in it. Change
function mygroups() {
to
function Mygroups() {

Related

Image not getting displayed in react project

This is my App.js. Here, I call the "Profile" Component.
import './App.css';
import Profile from "./Profile"
function App() {
return (
<div className="App">
<Profile />
</div>
);
}
export default App;
Then, inside Profile.js, I call Card component and inside the Card component, I've enclosed an image.
import React from 'react'
import Card from './Card'
import styles from "./Profile.module.css"
import image1 from "./assets/profile1.png"
const Profile = () => {
return (
<Card>
<div>
<img src={image1} alt="" />
</div>
</Card>
)
}
export default Profile
Inside of Card component, I've just applied some CSS to make it look like a Card.
import React from 'react'
import styles from "./Card.module.css"
const Card = () => {
return (
<div className={styles.card}>
</div>
)
}export default Card
This is my folder structure.
I'm really confused why the image isn't getting showed up. Currently this is the output I'm getting.
I've restarted the server as well. But it's not getting fixed.
your card doesn't have a child component return maybe that could be the problem
import React from 'react'
import styles from "./Card.module.css"
const Card = ({children}) => {
return (
<div className={styles.card}>
{children}
</div>
)
}
export default Card
try this

React & Typescript Issue: trigger elements with InsertionObserver using props and manage them in other component

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.

How to correct React Portal error: Target container is not a DOM element

im having an issue getting react portals working. I dont understand why I am receiving error message portal id is not DOM element that is clearly a valid DOM element.
I have a sandbox here
Code in its entirety presented here. The console.log reports correctly that the element is a DOM element but React is throwing an error.
import "./styles.css";
import { createPortal } from "react-dom";
import { useEffect, useState } from "react";
export default function App() {
const [portalDiv, setPortalDiv] = useState(undefined);
useEffect(() => {
let pd = document.getElementById("portalDiv");
console.log(pd);
setPortalDiv(pd);
}, []);
return (
<>
<div id="portalDiv">portal container</div>
<div className="app">
{/* {console.log("render portaldiv", portalDiv)} */}
{
(portalDiv &&
createPortal(
<>
<h1>Inside portal</h1>
</>
),
portalDiv)
}
<h1>Outside portal</h1>
</div>
</>
);
}
Any advice appreciated. Thanks.
This usecase is not recommended as stated in my comment, but here is a reproducible example.
If you intend to inject a React Node into VDOM, you should use React API for that, so you won't get a race condition while querying the DOM via DOM API.
import "./styles.css";
import { createPortal } from "react-dom";
import { useRef } from "react";
export default function App() {
const containerRef = useRef();
return (
<>
<div ref={containerRef}>portal container</div>
<div id="app">
{containerRef.current &&
createPortal(<h1>Example Element</h1>, containerRef.current)}
<h1>Outside portal</h1>
</div>
</>
);
}

Is there anyway to execute React JS hook from parent in child component?

I have this component "Board", there's other 3 components: TopBar, SandToHide and TreasureBoxes.
I just want that the TopBar component reads the "money" value and the TreasureBoxes executes the increment of money. The TopBar is reading the value that i'm setting in Board, but the TreasureBoxes doesn't seems to be executing the increment of the money.
Thanks in advance!
Board/index.js:
import React, { useState, useEffect } from "react";
import "./index.scss";
import { FaBomb, FaBox, FaFlag } from "react-icons/fa";
import img from "../../assets/ItemsToHide/barrels/barrel1.png";
import TreasureBoxes from "../TreasureBoxes";
import TopBar from '../TopBar';
import SandToHide from "../SandToHide";
const Board = ({ treasureBoxes, randomTop, randomLeft, sand}) => {
const [money, setMoney] = useState(0);
return (
<div className="board-container">
<TopBar money={money}></TopBar>
<div className="sand-to-hide-container">
{sand.map((sandd) => {
return (
<SandToHide
id={sandd.id}
img={sandd.img}
randomTop={randomTop}
randomLeft={randomLeft}
/>
)
})}
</div>
<div className="treasure-boxes-container">
{treasureBoxes.map((box) => {
return(
<TreasureBoxes
setMoney={setMoney}
money={money}
id ={box.id}
bomba = {box.bomba}
treasureBoxes={treasureBoxes}
randomTop={randomTop}
randomLeft={randomLeft}
/>
)
})}
</div>
</div>
);
};
export default Board;
Just make sure to have a callback in your TreasureBoxes component (it would be easier to answer to you if you provided the code for it):
<input onChange={(e)=> setMoney(e.target.value)}/>

How to refactor react hooks nested function properly

I have a function component which uses two states and both are changed based on event triggered.
I've read on react docs that is a bad idea to change states in nested function or condition. I also seen some examples using useEffects, but I have no clear idea how to properly refactor this.
here is my entire component:
import React, { useState, useEffect } from 'react'
import './App.css'
import AppHeader from '../app-header'
import AppFooter from '../app-footer'
import SearchInput from '../search-input'
import Stats from '../stats'
import Chart from '../chart'
import { getBundleInfoAPI } from '../../services/hostApi'
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css'
import Loader from 'react-loader-spinner'
function App() {
const [isSpinnerVisible, setSpinnerVisible] = useState(false)
const [bundleData, setBundleData] = useState({})
const _handleOnItemSelected = (item) => {
if (item && item.package && item.package.name && item.package.version) {
setSpinnerVisible(true)
getBundleInfoAPI(item.package.name, item.package.version)
.then(resposeData => setBundleData(resposeData))
.finally(() => setSpinnerVisible(false))
} else {
// TODO - implement an error handler component?
console.warn('WARNING: The selected bundle does not have name or version!')
}
}
return (
<div className="app">
<AppHeader />
<main>
<SearchInput onItemSelected={_handleOnItemSelected} />
<div className="app-main-inner-container">
<Loader type="Triangle" color="#00BFFF" height={200} width={200} visible={isSpinnerVisible} />
{!isSpinnerVisible &&
<div className="app-stats-chart-container">
<section className="app-stats-container"><Stats size={bundleData.stats} /></section>
<section className="app-chart-container"><Chart bundleChartData={bundleData.chart} /></section>
</div>
}
</div>
</main>
<AppFooter />
</div>
)
}
export default App
Docs section you are referring to means you must not put line with useState inside of nested functions, conditions, loops.
Calling setter returned by hook is definitely fine and correct.
This is fine, you are showing the loading screen when starting fetch and then hiding it when the fetch is done... no refactoring needed

Resources