react/no-multi-comp is showing up as warnings - javascript

I am using hook router 1.2.5 and I have a very simple home page as below:
import { useRoutes } from "hookrouter";
import React from "react";
import Nav from "./pages/Nav";
import AboutPage from "./pages/About";
const HomePage = () => {
const routeResult = useRoutes({
"/about": () => <AboutPage />
});
return (
<div fluid>
<div xs={3} md={1} lg={1} className="nav-container">
<Nav />
</div>
<div xs={9} md={11} lg={11}>
{routeResult || <AboutPage />}
</div>
</div>
);
};
export default HomePage;
But when I run lint, I see below warnings show up.
8:10 warning Component definition is missing display name react/display-name
8:10 warning Declare only one React component per file react/no-multi-comp
I know I can disable these eslint warnings. But I would like to know how to fix them. For example, I don't have another component in my file. So why would it show react/no-multi-comp warning, or did I miss something? Any helps are appreciated.
UPDATE
I was able to fix react/display-name by replacing the arrow function as below:
const routeResult = useRoutes({
"/about"() {
return <AboutPage />;
}
});

Related

Loading page on nextjs 13

Hi im trying to get a loading page to show while website is taking the time to load. as it quite a large website I thought a loading screen would provide the best possible user experience however I cannot seem to figure out how to get it to work on nextjs 13. I have created a simple functional component that says loading... and have imported it directly into my layout.jsx folder.
I am using the app directory method which is quite new and im also new at nextjs so im a little lost ^^
I imagine I might need to set state at some point but I cant seem to figure out when and where to do it
any advice would be great.
thanks
import "./globals.css";
import React, { useState, useEffect } from "react";
import Loading from "../components/loading/loading";
const Layout = ({ children, dataLoaded }) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
if (dataLoaded) {
setLoading(false);
}
}, [dataLoaded]);
return (
<body className="app {oswald.className}">
{loading && <Loading />}
{children}
</body>
);
};
export default Layout;
.
.
.
Attempt 1 -
After following one of the answers below it does not seem like my loading page is showing up at all. and no errors showing up.
my layout is as follows
layout.jsx
import "./globals.css";
import { Suspense } from "react";
import Loading from "../components/loading/loading";
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<Suspense fallback={<Loading />}>{children}</Suspense>
</body>
</html>
);
}
LoadingPage.js
const LoadingPage = () => {
return (
<div className="loading w-screen h-screen bg-red-100">
<p>Loading...</p>
</div>
);
};
export default LoadingPage;
Loading.js
import LoadingPage from "#/components/loading/loading";
export default function Loading() {
return <LoadingPage />;
}
In NextJS 13, there's actually a default way to handle loading states within pages. You can declare a loading.tsx file in your /app directory, with this content:
export default function Loading() {
return <Loading />
}
Then, inside your Layout, you can wrap your page with a Suspense tag, like this:
<Layout>
<Navbar>
...
<Suspense fallback={<Loading/>}>
<Page/>
</Suspense>
</Layout>
Your loading state will be automatically handled upon navigation.

Why can't I import this CardList in JSX?

I'm doing with my homework about React.
I'm tring to add Cards to the page and I created a Card.jsx and a CardList.jsx file to achieve this. And I used the faker to help generating some random fake info. However, when I imported the CardList.jsx to the App.js file and ran it, I saw nothing but while page on the browser. I just dont know why and I've almost copy the same as the teacher gave.
Please help me!
Here are the codes:
Card.jsx:
import React from "react";
const Card = (props) => {
return (
<div>
<img src={props.avatar} alt="food" />
<h3>{props.article_name}</h3>
<p>{props.description}</p>
<h4>{props.author_name}</h4>
</div>
)
}
export default Card
CardList.jsx
import React from "react";
import Card from './Card'
import { faker } from '#faker-js/faker'
const CardList = () => {
return (
<div>
<Card
avatar={faker.image.fashion()}
article_name={faker.definitions.title()}
description={faker.lorem.paragraph()}
author_name={faker.name.firstName + ' ' + faker.name.lastName}
/>
</div>
)
}
export default CardList
App.js
import './App.css';
import CardList from './CardList'
function App() {
return (
<div className="App">
<CardList />
</div>
);
}
export default App;
overview of the vs code
In your CardList.jsx change code to this :
<div>
<Card
avatar = {faker.image.fashion()}
article_name = {faker.definitions.title}
description = {faker.lorem.paragraph()}
author_name = {faker.name.firstName() + ' ' + faker.name.lastName()}
/>
</div>
Since faker.definitions.title is not a function. If you would open your browser console, you will see an error message regarding the same.Please make sure you write functions as functions and variables as variables by reading documentation.
firstName and lastName are functions so they need parentheses https://fakerjs.dev/api/name.html
Looking through the documentation, faker.definitions.title doesn't exist so you will need to use some other type of date for article_name
<div>
<Card
avatar={faker.image.fashion()}
article_name={faker.commerce.productName()} //using this as an example. replace with what you want
description={faker.lorem.paragraph()}
author_name={faker.name.firstName() + ' ' + faker.name.lastName()}
/>
</div>

React Props not passing down to children components?

I am trying to learn React so please bear with me!
I am following a tutorial to help me understand react and how you can pass down components.
I am trying to pass props down 2 levels, but when I render the code on the third element, nothing appears on the page. Using React Dev tools on chrome, it seems that the props are loading on the Tweets.js component rather than the Tweet.js component.
Can anybody tell me whats wrong? The order is App.js > Tweets.js > Tweet.js
For ref, I am following the following tutorial, it is around the 15 min mark.
React State and Props | Learn React For Beginners Part 4
App.js
import './App.css';
import Tweets from './components/Tweets';
import React from 'react';
function App() {
const name=["Name1", "Name2", "Name3"];
const age=["21", "22", "24"]; /* Data is created here */
return (
<div className="App">
<Tweets me={name} age={age} />{/*Data is added to component*/ }
</div>
);
}
export default App;
Tweets.js
import Tweet from './Tweet';
const Tweets = (props) => (
<section>
<Tweet />
</section>
);
export default Tweets;
Tweet.js
const Tweet = (props) => (
<div>
<h1>{props.me}</h1>
<h1>{props.age}</h1>
</div>
);
export default Tweet;
You would need to transfer props through your Tweets component:
const Tweets = (props) => (
<section>
<Tweet {...props} />
</section>
);

react-admin edit component does not call update function

I'm working on a react-admin application and having an issue where the update function in my dataProvider is not called when the 'Save' button is clicked under the edit view.
My App.js looks like this:
import React, { useEffect } from 'react';
import { Switch, Route, Redirect, useLocation } from 'react-router-dom';
import { setGlobal, getGlobal } from 'reactn';
import ReactGA from 'react-ga';
import PrivateRoute from './Auth/PrivateRoute';
import UserLayout from './components/user/layout/Layout';
import AuthLayout from './components/auth/Layout';
import defaultGlobalState from './defaultGlobalState';
import portalApiDataProvider from "./providers/portalApiDataProvider";
import {Admin, ListGuesser, EditGuesser, ShowGuesser, Resource, Layout} from "react-admin";
import { UserList, UserEdit, UserShow } from '../src/components/admin/users';
import { AccountList } from "./components/admin/serviceAccounts";
import authProvider from "./providers/authProvider";
ReactGA.initialize(process.env.REACT_APP_GA_KEY);
const jwt = JSON.parse(localStorage.getItem('jwt'));
setGlobal({ ...defaultGlobalState, jwt });
const App = () => {
const { userId } = getGlobal();
let location = useLocation();
useEffect(() => {
ReactGA.pageview(location.pathname + location.search);
}, [location]);
return (
<Admin dataProvider={portalApiDataProvider} authProvider={authProvider}>
<Resource name="users" options={{label: 'Customer Profiles'}} list={UserList} show={UserShow} edit={UserEdit}/>
<Resource name="serviceAccounts" list={AccountList}/>
</Admin>
);
};
export default App;
My UserEdit is as follows:
<Edit title={<UserTitle/>} {...props}>
<SimpleForm>
<TextInput source="first_name" />
<TextInput source="last_name" />
<TextInput source="email" />
<TextInput source="phone" />
<TextInput source="default_account_number" />
<BooleanInput source="validated" format={v => v === 1 ? true : false}/>
</SimpleForm>
</Edit>
I've seen this issue brought up a couple of times, but without any details on resolution. This link mentions using a Notification component in the Layout (I'm pretty sure I'm using the default layout), or disabling undo (which does work but is not ideal): https://github.com/marmelab/react-admin/issues/3049
This link also discusses a similar issue with reference to a demo project, but I'm not able to find the relevant code: https://github.com/marmelab/react-admin/issues/5082
What am I missing here?
For some reason, the undoable prop on Edit is causing problem. Set it to false and it will call the update properly. I don't know why, I am using this under a special endpoint as a "sub-app", so might be due to conflicting routers, too tired to find out.
You should set the mutationMode of Edit into "pessimistic"
So your will be
<Edit
{...props}
mutationMode="pessimistic"
>
Document here: https://marmelab.com/react-admin/CreateEdit.html#mutationmode

Using APIs in a React Template

I am learning the ropes of React and JavaScript. I started by grabbing a free template I found from GitHub. After creating a few other pages, I connected the app to a Django back end and created a model with two entries.
The objective is to be able to display the information from the model like title, objective, etc. I'm also new to using APIs to get this information, so I've been looking through various places online, but I just can't figure out how to fit in the code examples online with the code I have from the template from GitHub.
One of the places I've looked: https://reactjs.org/docs/faq-ajax.html
Below is Hero.js. This is routed to the home page and it's just what the template provider named it. The code example provided above and in many other places I've looked puts all their code in App.js. I know they're just doing that for demonstration purposes, but I'm not sure how to fit it into the template code.
import React, { useState } from 'react';
import classNames from 'classnames';
import { SectionProps } from '../../utils/SectionProps';
import ButtonGroup from '../elements/ButtonGroup';
import Button from '../elements/Button';
import Image from '../elements/Image';
import { Link } from 'react-router-dom';
const propTypes = {
...SectionProps.types
}
const defaultProps = {
...SectionProps.defaults
}
const Hero = ({
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
...props
}) => {
const outerClasses = classNames(
'hero section center-content',
topOuterDivider && 'has-top-divider',
bottomOuterDivider && 'has-bottom-divider',
hasBgColor && 'has-bg-color',
invertColor && 'invert-color',
className
);
const innerClasses = classNames(
'hero-inner section-inner',
topDivider && 'has-top-divider',
bottomDivider && 'has-bottom-divider'
);
return (
<section
{...props}
className={outerClasses}
>
<div className="container-sm">
<div className={innerClasses}>
<div className="hero-content">
<h1 className="mt-0 mb-16 reveal-from-bottom" data-reveal-delay="200">
BlueBird <span className="text-color-primary">Teaching</span>
</h1>
<div className="container-xs">
<p className="m-0 mb-32 reveal-from-bottom" data-reveal-delay="400">
An open source approach to education.
</p>
<div className="reveal-from-bottom" data-reveal-delay="600">
<ButtonGroup>
<Button tag="a" color="primary" wideMobile>
<Link to="/About">How This Works</Link>
</Button>
<Button tag="a" color="dark" wideMobile>
<Link to="/Test">Other Open Source Resources</Link>
</Button>
</ButtonGroup>
</div>
</div>
</div>
<div className="hero-figure reveal-from-bottom illustration-element-01" data-reveal-value="20px" data-reveal-delay="800">
<h2>Current Focus:</h2>
<h3 style={{ color: '#5b92e5' }}>(title)</h3>
<p style={{ textAlign: 'left', color: 'white' }}><strong>Objective: </strong>(Objective goes here)</p>
<p style={{ textAlign: 'left', color: 'white' }}>(Description goes here)</p>
<p style={{ textAlign: 'left', color: 'white', fontSize: 15 }}>The expected completion date of this focus is: (expected_completion_date)</p>
<h3>Preview</h3>
<Image style={{ padding: '30px' }}
src={require('./../../assets/images/Screenshot from 2020-08-03 07-52-33.png')}
alt="Hero"
width={896}
height={504} />
<Image
src={require('./../../assets/images/Screenshot from 2020-08-03 07-53-08.png')}
alt="Hero"
width={896}
height={504} />
</div>
</div>
</div>
</section>
);
}
Hero.propTypes = propTypes;
Hero.defaultProps = defaultProps;
export default Hero;
If needed, below is App.js.
import React, { useRef, useEffect } from 'react';
import { useLocation, Switch } from 'react-router-dom';
import AppRoute from './utils/AppRoute';
import ScrollReveal from './utils/ScrollReveal';
import ReactGA from 'react-ga';
// Layouts
import LayoutDefault from './layouts/LayoutDefault';
// Views
import Home from './views/Home';
import Test from './views/test';
import About from './views/About';
import Contact from './views/Contact';
// Initialize Google Analytics
ReactGA.initialize(process.env.REACT_APP_GA_CODE);
const trackPage = page => {
ReactGA.set({ page });
ReactGA.pageview(page);
};
const App = () => {
const childRef = useRef();
let location = useLocation();
useEffect(() => {
const page = location.pathname;
document.body.classList.add('is-loaded')
childRef.current.init();
trackPage(page);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);
return (
<ScrollReveal
ref={childRef}
children={() => (
<Switch>
<AppRoute exact path="/" component={Home} layout={LayoutDefault} />
<AppRoute exact path="/test" component={Test} layout={LayoutDefault} />
<AppRoute exact path="/about" component={About} layout={LayoutDefault} />
<AppRoute exact path="/contact" component={Contact} layout={LayoutDefault} />
</Switch>
)} />
);
}
export default App;
Thanks for any help and explanations!
So you just want to get your data from API and use it in your application.
Here is an little example for you with comments
import React, { useState, useEffect } from "react";
export default function Example() {
// Define our datas variable in state as an empty Array
const [datas, setDatas] = useState([]);
// useEffect will called after component will be rendered
useEffect(() => {
// Fetch our data from our API
fetch("https://jsonplaceholder.typicode.com/todos/")
// Resolve the responsove data
.then((response) => response.json())
.then((json) => {
// Show data in console
console.log(json)
// Set our API data to our datas array
setDatas([...json]);
});
}, []);
return (
<div>
<ul>
{/*
map is a build-in javascript function too loop through objects like foreach
So we just loop our array and render in our application
*/}
{datas.map((data, i) => (
<li key={i}> {data.title} </li>
))}
</ul>
</div>
);
}
I use javascript Fetch API function to get data from API but if you want, you can use something like Axios too.
If we want to use axios we just need to change useEffect like this for example;
First we need to install axios
npm install axios
Then, import or require axios
import axios from "axios";
// or
const axios = require('axios');
After these steps, just change useEffect function like this;
axios.get("https://jsonplaceholder.typicode.com/todos/")
.then(function (response) {
// handle success and show data in console
console.log(response.data);
// Set our API data to our datas array
setDatas([...response.data]);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
Javascript MAP: Array.prototype.map() - Mozilla Developers
Fetch API: Fetch API - Mozilla Developers
Axios: Axios Github Page
Axios vs Fetch API: Fetch vs. Axios.js for making http requests
Also I would suggest you to build your app from scratch rather than using a template to understand better and remember I just gave you a simple example, if you wanna build something for production you may want to build a different structure for your API requests.
I hope I could help, have a great day :)

Categories

Resources