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.
Related
Could you please help use to resolve this case
Parent component
const HelloMessage = (props) => {
return <>
<div className="main-counter" >
<top-destination name="srini" />
</div>
</>
}
export default HelloMessage
customElements.define("react-counter", reactToWebComponent(HelloMessage, React, ReactDOM));
Child (Web component)
import React from 'react';
import reactToWebComponent from "react-to-webcomponent";
const TopDestination = (props) => {
console.log(props);
return <>
<div>{props.name}</div>
</>
}
export default TopDestination
customElements.define("top-destination", reactToWebComponent(TopDestination, React, ReactDOM));
console log value
In html
<top-destination name="John" />
Cross-check your Node version, It should be Node 14 or above.
Cross-check your import ReactDom statement, based on the React version you are using.
Update to the latest version of react-to-webcomponent and prop-types
Your code should be like this:
Parent component
import React from 'react';
const HelloMessage = (props) => {
return <>
<div className="main-counter" >
<top-destination name="srini" />
</div>
</>
}
export default HelloMessage
customElements.define("react-counter", reactToWebComponent(HelloMessage, React, ReactDOM));
Child (Web component)
import React from 'react';
import PropTypes from "prop-types"
import * as ReactDOM from 'react-dom/client';
import reactToWebComponent from "react-to-webcomponent"
const TopDestination = (props) => {
console.log(props);
return <>
<div>{props.name}</div>
</>
}
TopDestination.propTypes = {
name: PropTypes.string,
}
customElements.define("top-destination", reactToWebComponent(TopDestination, React, ReactDOM));
export default TopDestination
// Other ways of defining the props if you are on better versions.
// customElements.define(
// "top-destination",
// reactToWebComponent(TopDestination, React, ReactDOM, {
// props: {
// name: String
// },
// }),
// )
// or
// customElements.define(
// "top-destination",
// reactToWebComponent(TopDestination, React, ReactDOM, {
// props: ["name"]
// }),
// )
Refer this repo: https://github.com/sarat9/cross-ui-web-comp
File: https://github.com/sarat9/cross-ui-web-comp/blob/master/react-web-components/src/web-components/FancyButtonWC.js
I bought this template and am trying to understand which page getLayout in this code"{getLayout(<Component {...pageProps} />)}" goes to on initial load. I'm guessing it's a global variable somewhere, but I can't find it using the definitions. I'm trying to under the next.js documentation, but I'm having issues. If anyone has a good tutorial for this I'll happily take it.
import type { AppProps } from 'next/app';
import { appWithTranslation } from 'next-i18next';
import { SessionProvider } from 'next-auth/react';
import '#/assets/css/main.css';
import 'react-toastify/dist/ReactToastify.css';
import { ToastContainer } from 'react-toastify';
import { ModalProvider } from '#/components/ui/modal/modal.context';
import ManagedModal from '#/components/ui/modal/managed-modal';
import ManagedDrawer from '#/components/ui/drawer/managed-drawer';
import DefaultSeo from '#/components/seo/default-seo';
import { SearchProvider } from '#/components/ui/search/search.context';
import PrivateRoute from '#/lib/private-route';
import { CartProvider } from '#/store/quick-cart/cart.context';
import SocialLogin from '#/components/auth/social-login';
import { NextPageWithLayout } from '#/types';
import QueryProvider from '#/framework/client/query-provider';
import { getDirection } from '#/lib/constants';
import { useRouter } from 'next/router';
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
function CustomApp({
Component,
pageProps: { session, ...pageProps },
}: AppPropsWithLayout) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
const authenticationRequired = Component.authenticationRequired ?? false;
const { locale } = useRouter();
const dir = getDirection(locale);
return (
<div dir={dir}>
<SessionProvider session={session}>
<QueryProvider pageProps={pageProps}>
<SearchProvider>
<ModalProvider>
<CartProvider>
<>
<DefaultSeo />
{authenticationRequired ? (
<PrivateRoute>
{getLayout(<Component {...pageProps} />)}
</PrivateRoute>
) : (
getLayout(<Component {...pageProps} />)
)}
<ManagedModal />
<ManagedDrawer />
<ToastContainer autoClose={2000} theme="colored" />
<SocialLogin />
</>
</CartProvider>
</ModalProvider>
</SearchProvider>
</QueryProvider>
</SessionProvider>
</div>
);
}
export default appWithTranslation(CustomApp);
Basically, you can define a per component layout. In order to do so, when you are defining a component, you add a property named getLayout. Here's an example, for a better understanding.
// ...
const Component: React.FC = () => <div>
I have a custom layout
</div>
// Here we define a layout, let's imagine it's a component
// we have inside /layouts and we have previously imported it
Component.getLayout = (page: React.ReactElement) =>
<LayoutComponent>{page}</LayoutComponent>
Now, when a page is rendered (note that in a Next JS app, all pages are rendered as a children of what is inside _app.{js,jsx,ts,tsx}) your code checks if the prop getLayout has been defined or not. Then, it is basically calling such function, if exists, otherwise it renders the base component.
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
I'm trying to do a pretty basic Flashcard application in react. I'm very new to it so I apologize in advance if my code is riddle with errors, or just poorly done. I am just trying to run a very simple test on my component with jest to see if it renders without crashing. My application runs fine when I just yarn start from the command line but the test keeps failing. Any help would be much appreciated!
CardList component
import React from 'react';
import Card from './Card';
export default function CardList({ cards }) {
return (
//grid styling so that the app can be responsive no matter the screen size
<div className="my-grid">
{cards.map(card => {
//return card component only re renders unique elements
return <Card card={card} key={card.id} />
})}
</div>
)
}
` That's the code for the component, then below is the test:
import React from 'react';
import ReactDOM from 'react-dom';
import CardList from './CardList';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<CardList />, div);
});
You should pass cards as a prop of the CardList component.
E.g.
CardList.jsx:
import React from 'react';
import Card from './Card';
export default function CardList({ cards }) {
return (
<div className="my-grid">
{cards.map((card) => {
return <Card card={card} key={card.id} />;
})}
</div>
);
}
Card.jsx:
export default function Card({ card }) {
return <div>{card.name}</div>;
}
CardList.test.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import CardList from './CardList';
it('renders without crashing', () => {
const cards = [{ id: 1, name: 'teresa teng' }];
const div = document.createElement('div');
ReactDOM.render(<CardList cards={cards} />, div);
});
unit test result:
PASS src/stackoverflow/64817280/CardList.test.jsx (11.207s)
✓ renders without crashing (22ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.292s
I would like to make my array of jokeComponents gets filtered to only display those that have fewer than X number of characters in the question.
How can I implement the filter method to this code without deleting map method?
import React from "react"
import Joke from "./Joke"
import jokesData from "./jokesData"
function App() {
const jokeComponents = jokesData.map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />)
return (
<div>
{jokeComponents}
</div>
)
}
export default App
jokesData.filter(joke => joke.question.length > X).map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />)
Try this.
You could so something like this? Whereby you filter your array of components by perform your predicated function against the question prop. And then render the filtered array (if that's the intended outcome)
import React from "react"
import Joke from "./Joke"
import jokesData from "./jokesData"
function App() {
const jokeComponents = jokesData.map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />);
const filteredJokes = jokeComponents.filter((component) => component.props.question.length > 2);
return (
<div>
{filteredJokes}
</div>
)
}
export default App
This is initially filter out array with elements having question length less than value X.
import React from "react"
import Joke from "./Joke"
import jokesData from "./jokesData"
function App() {
const jokeComponents = jokesData.filter(ele=>{ele.question.length>X}).map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />)
return (
<div>
{jokeComponents}
</div>
)
}
export default App
import React from "react"
import Joke from "./Joke"
import jokesData from "./jokesData"
function App() {
const filteredJokes = jokesData.filter(joke => joke.question.length > X);
return filteredJokes.map(joke => <Joke key={joke.id} {...joke} />)
}
export default App