import React from 'react';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { useLocation, Link, useNavigate } from 'react-router-dom';
function App() {
const temp = useLocation();
const [username, changeUsername] = useState("guest")
const [password, changePassword] = useState("guest")
const [id, changeId] = useState(-1)
const [data,changeData]=useState(null);
useEffect(() => {
if (temp.state !== null) {
changeUsername(temp.state.username);
changePassword(temp.state.password);
changeId(temp.state.id)
}
},[])
useEffect(() => {
if (id !== -1) {
//fetchdata with axios
changeData(fetchedData)
}
},[id])
return (
<div>
{data!==null && data.map(a => (DataComponent(a))}
</div>
);
}
export default App;
DataComponent also uses react hooks... When I try this with some local data it works, but with fetched data I get "Rendered more hooks than during the previous render".
Related
This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 4 months ago.
I am having a problem getting the router.query to pull back the params of the url.
I have tried several different ways of approaching this problem and think that i am using the right solution. However, I keep getting an undefined result.
Here is the query param highlighted in yellow...
/pages/artist/[artistId].js
import React, { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { getDoc, doc } from "firebase/firestore";
import { db } from "../api/auth/firebase/config";
import Head from "next/head";
import ArtistHeader from "../../components/ArtistHeader";
import UploadButton from "../../components/UploadButton";
import styles from "../../styles/artistPage.module.css";
export default function Artist() {
const { data: session, status, loading } = useSession();
const [artist, setArtist] = useState();
const router = useRouter();
const { artistId } = router.query;
useEffect(() => {
if (status === "unauthenticated") {
router.push("/auth/signin");
}
}, [status, loading, router]);
// useEffect to fetch artist page data
useEffect(() => {
const fetchArtist = async () => {
const artistRef = doc(db, "users", `${artistId}`);
const docSnap = await getDoc(artistRef);
setArtist(docSnap);
};
fetchArtist();
}, [setArtist, artist, artistId]);
return (
<section className={styles.wrapper}>
<Head>
<title>{artist.screenName}</title>
</Head>
<div className={styles.artistPage}>
<ArtistHeader artist={artist} />
<div className={styles.songContainer}>
<UploadButton />
</div>
</div>
</section>
);
}
Is this problem being caused by the router not being ready and the page is trying to render before it is able to get the params?
Bit lost here and could use some pointers. Thanks in advance.
It should be either,
const { artistId } = router.query;
or
const artistId = router.query.artistId;
The problem was that i would get undefined when getting the router.query due to the useEffect being actioned before the router was finished doing its operation. now my code looks like that and works...
import React, { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { getDoc, doc } from "firebase/firestore";
import { db } from "../api/auth/firebase/config";
import Head from "next/head";
import ArtistHeader from "../../components/ArtistHeader";
import UploadButton from "../../components/UploadButton";
import styles from "../../styles/artistPage.module.css";
export default function Artist() {
const { data: session, status, loading } = useSession();
const [artist, setArtist] = useState();
const router = useRouter();
const artistId = router.query.artistId;
useEffect(() => {
if (status === "unauthenticated") {
router.push("/auth/signin");
}
const fetchArtist = async () => {
if (!router.isReady) return;
const artistRef = doc(db, "users", `${artistId}`);
const docSnap = await getDoc(artistRef);
setArtist(docSnap);
};
fetchArtist();
}, [status, loading, router, artistId]);
return (
<p> it works </p>
}
I'm trying to pass a JSON object (id) returned from an API call to another component via props and use that object(id) to fetch more data from a different endpoint. The problem is, when i pass the prop using object literal to the api, it gives an error undefined but when i console log the object(id) it works fine. What could be the issue? Just started learning React.
component passing object as prop
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import Cast from "./Cast";
const DetailsView = () => {
const { id } = useParams();
const [details, setDetails] = useState([]);
useEffect(() => {
axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=<<api_key>>&language=en-US`
)
.then((response) => {
setDetails(response.data);
});
}, []);
return (
<div className="w-full h-[650px] text-white">
<<bunch of code>>
<Cast id={details?.id}/>
</div>
);
};
export default DetailsView;
component receiving prop
import React, { useState, useEffect } from "react";
import axios from "axios";
const Cast = (props) => {
const [cast, setCast] = useState([]);
const sid = props.id;
useEffect(() => {
axios
.get(
`https://api.themoviedb.org/3/movie/${sid}/credits?api_key=<<api_key>>&language=en-US`
)
.then((response) => {
setCast(response.data.cast);
console.log(response.data.cast);
});
}, []);
console.log(sid);
return (
<div className="absolute">
{cast && cast.map((item, index) => <p className="">{item.name}</p>)}
<p>{sid}</p>
</div>
);
};
export default Cast;
It doesn't work initially but when I edit the code, since the change is happening live, it fetches the data but when I refresh the page, Axios reports an error 404
xhr.js:220 GET https://api.themoviedb.org/3/movie/**undefined**/credits?api_key=56fbaac7fd77013cc072d285a17ec005&language=en-US 404
Your id property does not exist until the API call is completed, and there is a rerender after setDetails.
You can check if id exists and based on that render your Card component. Also, looks like details is an object not an array, so I changed the useState statement to reflect that.
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import Cast from "./Cast";
const DetailsView = () => {
const { id } = useParams();
const [details, setDetails] = useState({});
useEffect(() => {
axios
.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=<<api_key>>&language=en-US`
)
.then((response) => {
setDetails(response.data);
});
}, []);
return (
<div className="w-full h-[650px] text-white">
<<bunch of code>>
{details?.id && <Cast id={details?.id}/>}
</div>
);
};
export default DetailsView;
i am new in react, how to showing (accountInfo[4]) value in my website?
when i changed to
const setPaid = (accountInfo[4])
TypeError: Cannot read property '4' of undefined
import React, { useState } from 'react';
import useAccountInfo from '../abi/useAccountInfo';
import Value from '../utils/value';
const Hero = () => {
const accountInfo = useAccountInfo();
const setPaid = console.log(accountInfo);
return (
<div>
<Value value={setPaid}/>
</div>
);
export default Hero;
this the result in console
this my useAccountInfo.js file
import { useEffect, useState } from 'react'
import { useWallet } from 'use-wallet'
import { BigNumber } from 'ethers';
import useBlock from './useBlock'
import useTokenInfo from './useTokenInfo';
const useAccountInfo = () => {
const [accountInfo, setAccountInfo] = useState(BigNumber.from(0));
const {account, ethereum} = useWallet();
const block = useBlock();
const tokenInfo = useTokenInfo();
const fetchAccountInfo = async () => {
if (!account) {
setAccountInfo(BigNumber.from(0));
return;
}
const accountInfo = await tokenInfo?.accountInfo();
setAccountInfo(accountInfo);
};
useEffect(() => {
fetchAccountInfo();
}, [block, account, ethereum, tokenInfo]);
return accountInfo;
}
export default useAccountInfo;
I've been studying react and developing an app, but i got a problem using context. In one component I create the context and provide its value, but when I try to use the current value of context in another component, I have userName:undefined in console.log(). Code:
import React, { useContext, useState } from 'react'
import EnterRoom from '../../Pages/EnterRoom'
import NameChoose from '../../Pages/NameChoose'
import Room from '../../Pages/Room'
export const AllInformation = React.createContext({userName:'default'}) as any
const InformationContextProvider:React.FC = () => {
const [userInformation,setUserInformation] = useState({userName:'newValue'})
return (
<AllInformation.Provider value={{userInformation, setUserInformation}}>
<Room/>
<NameChoose/>
<EnterRoom/>
</AllInformation.Provider>
)
}
export default InformationContextProvider
export function useInformationContext(){
const {userInformation} = useContext(AllInformation)
return { userInformation }
}
And i try to use here:
import React, { useState, FormEvent, useEffect, useContext} from 'react';
import './styles.css'
import { Link, useHistory } from 'react-router-dom';
import { useInformationContext } from '../../components/Context/index'
import io from 'socket.io-client';
function EnterRoom() {
const [roomId, setRoomId] = useState('');
const [name, setName] = useState('');
const history = useHistory();
const socket = io('http://localhost:3333');
const { userInformation } = useInformationContext()
useEffect(() => {
if(sessionStorage.getItem('userName') || sessionStorage.getItem('roomId')) {
history.push('/')
}
console.log({ userInformation })
})
return <h1>hello word</h1>
}
useInformationContext is destructing the context value, which means it's doing value.userInformation, but that key does not exist. Remove the destructuring since the value is not nested:
export function useInformationContext() {
// no destructuring needed here
const userInformation = useContext(AllInformation)
return { userInformation }
}
return directly the useContext hook without destructing.
export function useInformationContext() {
return useContext(AllInformation)
}
I'm trying to pass data with Context API to child components. Value is getting undefined upon fetching it from a component.
Component Hierarchy:
passing data to a component MockTable and UsecasePane
MainContent -> MockTable
MainContent -> AddMock -> TabContent -> UsecasePane
=> MockContext.js
import React, { useState, useEffect, createContext } from "react";
import axios from "axios";
export const MockContext = createContext();
// provider
export const MockProvider = (props) => {
const [data, setData] = useState([]);
// data fetch and setting the state
return (
<MockContext.Provider data={[data, setData]}>
{props.children}
</MockContext.Provider>
);
};
Note: I'm getting response from the API.
Now in MainContent, components are encapsulated as follows:
// MainContent.js
import React from "react";
import { MockProvider } from "../MockContext";
const MainContent = () => {
return (
<MockProvider>
<div>
<CustomerTable />
<AddMock />
<MockTable />
</div>
</MockProvider>
);
};
When I try to fetch the data in MockTable or in UseCasePane, value is undefined.
// MockTable.js
import React, { useState, useEffect, useContext } from "react";
import { MockContext } from "./MockContext";
const MockTable = () => {
const [data, setData] = useContext(MockContext);
console.log(data);
// rest of the code
}
Please correct me where I'm going wrong :)
I tried to pass a String as well from the context and fetched in a component like:
return (
<MockContext.Provider data={"Hello"}>
{props.children}
</MockContext.Provider>
);
// in MockTable.js
const value = useContext(MockContext); ==> undefined
The correct prop to pass into the Provider is value, not data. (See: Context.Provider)
import React, { useState, useEffect, createContext } from "react";
import axios from "axios";
export const MockContext = createContext();
// provider
export const MockProvider = (props) => {
const [data, setData] = useState([]);
const fetchData = async () => {
const response = await axios
.get(config.App_URL.getAllRoute, {
params: {
customHostName: config.host,
type: config.type,
},
})
.catch((error) => {
console.error(`Error in fetching the data ${error}`);
});
console.log(response.data);
setData(response.data);
};
useEffect(() => {
fetchData();
}, []);
return (
<MockContext.Provider value={[data, setData]}>
{props.children}
</MockContext.Provider>
);
};