I am working with React + JS in an app to render news of the NYTimes (https://developer.nytimes.com/). Well, the matter is that I want to render the most viewed in the last 7 days, but organized through categories or sections. And I have the problem with the rendering of my sections.
Here my app.js component:
import React, {useEffect, useState} from "react";
import ListOfSections from "./components/ListOfSections";
import getSections from "./services/getSections";
import Navbar from "./shared/Navbar/Navbar";
function App() {
const [section, setSection] = useState([]);
useEffect(() => {
getSections().then(sections=>setSection(sections));
}, [])
return (
<div>
<Navbar/>
<ListOfSections section={section}></ListOfSections>
</div>
);
}
export default App;
Here my ListOfSections component:
import React from 'react';
import Section from './Section';
export default function ListOfSections ({section}) {
return (
<div className="container_list_sections mt-4 ml-4">
{
section.map(({section})=>
<Section
section={section}
/>
)
}
</div>
)
};
And here my Section component:
import React from 'react';
export default function Section ({section}) {
return (
<div>
<h1 className="section-container mr-4">{section}</h1>
</div>
)
};
Well, the problem is when I do console.log(section) in the Section component, it returns me undefined. But if I do console.log(section) in ListOfSections component, it has received the information of the props. So... why when I am passing the prop section from ListOfSections to Section, is it undefined? Where is it the error? I dont understand. The result for the moment is this one:
Thanks :)
Your useEffect should look as follows:
const [sections, setSections] = useState([]);
...
useEffect(() => {
getSections().then(sections=>setSections(sections));
}, [])
When you get data back it seems to be an array of sections so it should be a plural.
So when you pass sections down as a prop, it should be:
<ListOfSections sections={sections}/>
Which then allows you to map in <ListOfSections>
export default function ListOfSections ({sections}) {
return (
<div className="container_list_sections mt-4 ml-4">
{
sections.map(section =>
<Section
section={section}
/>
)
}
</div>
)
};
For maps, you should also set a key, you can read more here
Related
I have a component in which i want to call different rtkquery hooks based on a condition. I am making a twitter clone and on the home page i want to call a getPostsList and on the profile page i want to call a getRetweetedPostsList but since the entire page is same apart from this i am using a single component. Now i want to call different hooks in the PostList component based on props? Is this possible? Maybe by using skip? Also is this against best practices?
index.tsx
import type { NextPage } from 'next'
import { useSession} from 'next-auth/react';
import SignUpLoginFullScreen from '../components/SignUpLoginFullScreen';
import LoadingScreen from '../components/LoadingScreen';
import PostsSection from '../components/Posts/PostsSection';
const Home: NextPage = () => {
const {data:session,status}=useSession();
return (
<>
{!session && status==='unauthenticated' &&
<SignUpLoginFullScreen/>
}
{!session && status==='loading' &&
<LoadingScreen/>
}
{session && status==='authenticated' &&
<PostsSection/>
}
</>
)
}
export default Home
PostSection.tsx
import React from 'react'
import { useSession} from 'next-auth/react';
import Sidebar from '../Sidebar';
import Search from '../Search';
import PostsList from '../Posts/PostsList';
import AddPostForm from '../Posts/AddPostForm';
import Modal from '../Modal';
import UsersList from '../UsersList';
const PostsSection=()=>{
const {data:session,status}=useSession();
return (
<>
<Modal>
<AddPostForm />
</Modal>
<div className='flex mx-32 gap-x-5'>
<Sidebar/>
<main className='mr-5 pt-8 flex-1 basis-[45%] border-x-2 border-stone-100 min-h-screen'>
<PostsList currUserId={session?.userId}/>
</main>
<div className='basis-[25%]'>
<Search/>
<UsersList currentUserId={session?.userId}/>
</div>
</div>
</>
)
}
export default PostsSection
PostList.tsx
import React from 'react'
import {useGetPostsQuery} from '../../services/apiSlice';
import LoadingSpinner from '../LoadingSpinner';
import Post from './Post';
interface PropsType{
currUserId:string|any
}
const mapPosts=(posts:any,currUserId:string)=>{
return posts?.map((post:any) => (
<Post key={post.id} currUserId={currUserId} {...post}/>
))
};
const PostsList:React.FC<PropsType>= ({currUserId}) => {
const {data:posts,isLoading,error,isError} = useGetPostsQuery(currUserId);
let content;
content=React.useMemo(()=>mapPosts(posts,currUserId), [posts]);
if(isLoading){
content=<LoadingSpinner/>
}
else if(isError){
let a:any=error
content=<p color='red'>{a?.message}</p>
}
else if(posts){
if(posts.length<=0){
console.log('aye')
content=<p color='black'>No tweets yet</p>;
return null;
}
}
return (
<section className="posts-list">
{content}
</section>
)
}
export default PostsList;
I want to call the PostList component from the profile page but with some props and based on that props i want to call a different hook to which i am calling for the index page.
Profile.tsx
import React from 'react';
import { useSession } from 'next-auth/react';
import LoadingScreen from '../components/LoadingScreen';
import Sidebar from '../components/Sidebar';
import Search from '../components/Search';
import PostsList from '../components/Posts/PostsList';
import AddPostForm from '../components/Posts/AddPostForm';
import Modal from '../components/Modal';
import UsersList from '../components/UsersList';
import SignUpLoginFullScreen from '../components/SignUpLoginFullScreen';
import PostsSection from '../components/Posts/PostsSection';
export default function Profile() {
const {data:session,status}=useSession();
return (
<>
{!session && status==='unauthenticated' &&
<SignUpLoginFullScreen/>
}
{!session && status==='loading' &&
<LoadingScreen/>
}
{session && status==='authenticated' &&
<PostsSection/>
}
</>
)
}
I would use different components to call different hooks, then pass the data to a reusable common component.
(code)
I have assigned the ref hook over the rightcompX div, when I render this component it will consol out undefined.
import React, { useRef, useState } from 'react';
import {gsap} from 'gsap';
import RingGraph from '../../../components/RingGraph/RingGraph';
import './CR.css';
const InterviewReport = (props) => {
const Cbox = useRef()
useState(()=>{
// gsap.from(CRbox.current,{opacity:0,duration:0.8,x:-40})
**console.log(Cbox)**
},[])
return (
<>
<div className="rightCompX" ref={Cbox}>
<div className="close" onClick={props.close}>
close
</div>
<div className="title">
candidate Report
</div>
.....
)
}
export default InterviewReport;
You probably meant to use useEffect() hook, not useState()
Error I am getting: ./src/components/IconsOne.js Attempted import error: 'TiHome' is not exported from 'react-icons/fa'.
IconsOne.js:
import { TiHome } from 'react-icons/fa';
const IconsOne = () => {
return (
<div className="homeIcon">
<h3>
<TiHome />
</h3>
</div>
)
}
export default IconsOne
App.js
import './App.css';
import IconsOne from "./components/IconsOne";
function App() {
return (
<div className="App">
<Router>
<IconsOne />
</Router>
</div>
);
}
export default App;
I am trying to build a navbar and the first step is to render a home icon. I used this page for documentation on importing icons for react: https://react-icons.github.io/react-icons/ and the name of the Icon that I'm trying to import is TiHome
The link to the icon is: https://react-icons.github.io/react-icons/search?q=tihome
Thank you.
The problem is fa, that is not the path for Typicons but for FontAwesome, so if you want TiHome from Typicons then according to react-icons you must use instead the ti path, so:
import { TiHome } from 'react-icons/ti';
const IconsOne = () => {
return (
<div className="homeIcon">
<h3>
<TiHome />
</h3>
</div>
)
}
export default IconsOne
I want to repeat my component for n times using react in ionic but i don't know how to that
for example in my Component.tsx i have:
import React from 'react';
import { IonCard, IonCardContent} from '#ionic/react';
const Component: React.FC = () => {
return(
<div>
<IonCard>
<IonCardContent>Hello From Ion Card</IonCardContent>
</IonCard>
</div>
)
};
export default Component;
And in my App.tsx I have:
import { IonApp} from '#ionic/react';
import '#ionic/react/css/core.css';
import '#ionic/react/css/normalize.css';
import '#ionic/react/css/structure.css';
import '#ionic/react/css/typography.css';
import '#ionic/react/css/padding.css';
import '#ionic/react/css/float-elements.css';
import '#ionic/react/css/text-alignment.css';
import '#ionic/react/css/text-transformation.css';
import '#ionic/react/css/flex-utils.css';
import '#ionic/react/css/display.css';
import './theme/variables.css';
import Component from './Component';
const App: React.FC = () => (
<IonApp className="ion">
<div>
{
// I want to repeat this
<Component />
}
</div>
</IonApp>
);
export default App;
I'm new to typescript and react, I would be so happy if you help
Thanks
You need a loop. The best loop here is map:
const App: React.FC = () => (
<IonApp className="ion">
<div>
{
Array(5).fill(null).map((_, i) => (
<Component key={i} />
))
}
</div>
</IonApp>
);
Don't forget that repeated components need to have a unique key prop in the loop.
And please pay attention to .fill(null). When you create an array using the Array function, it gets filled with empty values, and running .map method on it will fail. We have to fill it with a value (In this case null) in order to make it iterable.
as you may get from the title, passing props in react is not working. And i donĀ“t get why.
Main Ap Component
import './App.css';
import Licence from './Licence';
function App() {
return (
<>
<Licence>
test={"Test123"}
</Licence>
</>
);
}
export default App;
Other Component
import React from 'react';
const Licence = (props) => {
return (
<div>
<h1>name : {props.test}</h1>
</div>
)
}
export default Licence;
Problem
if i start the script and render the page, nothing is shown. What am I doing wrong?
Licence component looks good to me!
All you have to do is change up how you set it up on App. Props need to be passed on the tag, like this:
import './App.css';
import Licence from './Licence';
function App() {
return (
<>
<Licence test={"Test123"} />
</>
);
}
export default App;
update your App component:
```
<Licence
test={"Test123"} />
```
Pass like this
<Licence test={"Test123"} />
and access like this
const Licence = (props) => {
return (
<div>
<h1>name : {props.test}</h1>
</div>
)
}
Another way
<Licence>
Test123
</Licence>
access like this
const Licence = (props) => {
return (
<div>
<h1>name : {props.children}</h1>
</div>
)
}