NextJS Fast refresh not working as expected - reactjs

I am building a website with nextjs and Chakra UI. I am using emotion to style my navigation.
The code of navigation component is as follows:
import Link from "next/link";
import { Flex, List, ListItem } from "#chakra-ui/react";
import Image from "next/image";
import styled from "#emotion/styled";
const Nav = styled.nav`
position: sticky;
top: 20px;
z-index: 2;
`;
export default function StickyNav() {
return (
<Nav>
<Flex
bg='gray.100'
justifyContent='space-between'
p='8'
borderRadius='16'
>
<Image src='/vercel.svg' alt='Vercel Logo' width={72} height={16} />
<List display='flex' ml='4'>
<ListItem mr='8'>
<Link href='#about'>
<a>About</a>
</Link>
</ListItem>
<ListItem mr='8'>
<Link href='#projects'>
<a>Projects</a>
</Link>
</ListItem>
<ListItem>
<Link href='#contact'>
<a>Contact</a>
</Link>
</ListItem>
</List>
</Flex>
</Nav>
);
}
I am having trouble with Fast refreshing. When I start the dev server, the Navigation component picks up the styles correctly
const Nav = styled.nav`
position: sticky;
top: 20px;
z-index: 2;
`;
after serving, if I try to change the top position to 10px the fast refresh doesn't reflect those changes.
The fast refresh feature is working perfectly with other components but has problem with this specific component only. I have looked through several articles but not sure what's causing this behavior.

Check filename or foldername not started with a uppercase
Fast-refresh not works :
fast-refresh works :

Also check if your import statement has right casing.
import Box from '../Components/box';
vs
import Box from '../Components/Box';

in my case, the two words filename should use dash -, rather than underscore _.
For example:
good filename: hello-world.js
bad filename: hello_world.js

As #new2cpp and DeadBoyPiotrek Stated
When Importing your headers make sure your import statements match the file names.
Navbar.js <--Example File name
import Navbar from "../components/Navbar"
Not
import Navbar from "../components/navbar"
When I made this mistake the Fast Refresh would initially load then after changing something the Fast Refresh would continue rebuilding but never finish.

Related

Change Gatsby Link Behaviour - Stop Scroll Animation on Page Change

I'm sure this is going to be a very straight forward answer, but I can't for the life of me work out how to get my Gatsby/React site to start at the top of a new page without a scroll transition effect when I click on an internal link.
Example:
On my home page I scroll to the bottom, then click on a link to take me to an 'About Me' page. The About Me Page loads with the browser scroll position still at the bottom of the page and then the window scrolls to the top of the page. This only takes a few milliseconds but when I click on a link I want to start at the top of the page without any transition.
The links are all standard Gatsby Links:
<Link className="" to="/aboutme/">
About Me
</Link>
Thanks!
EDIT
Adding in my layout wrapper, with useScrollRestoration hooks added:
import React from 'react'
import PropTypes from 'prop-types'
import useScrollRestoration from 'gatsby'
import NavBar from './NavBar/NavBar'
import Footer from './Footer/Footer'
import './layout.scss'
const Layout = ({ children }) => {
const aboutMeScrollRestoration = useScrollRestoration(`page-component-main`)
return (
<>
<NavBar />
<main className="bumpdown" {...aboutMeScrollRestoration}>
{children}
</main>
<Footer />
</>
)
}
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
I managed to work this out in the end after a lot of Googling. It appears not to be a scrollRestoration issue but a Bootstrap issue. In bootstrap/scss/_reboot.scss there's the following code:
:root {
font-size: $font-size-root;
#if $enable-smooth-scroll {
#media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
}
This can be turned off either using $enable-reduced-motion: true; or $enable-smooth-scroll: false; in bootstrap overrides which stops the scrolling behaviour when a new page opens.
I'm using the enable-smooth-scrolling:false option as the other option may have further knock on effects.
I created a custom.scss file and imported it into the gatsby-browser.js file. The contents of the scss file is overriding the default value of the scroll-behaviour in bootstrap:
$enable-smooth-scroll: false;
:root {
scroll-behavior: auto !important;
}
#import "node_modules/bootstrap/scss/bootstrap";
This issue is known as Scroll Restoration. #reach/router (from where Gatsby extends its routing) handles it automatically. However, in some cases, it fails, especially when rendering containers that have their own scroll values. To bypass this "issue", Gatsby exposes a useScrollRestoration hook to restore the scroll position. For example:
import { useScrollRestoration } from "gatsby"
import countryList from "../utils/country-list"
export default function PageComponent() {
const ulScrollRestoration = useScrollRestoration(`page-component-ul-list`)
return (
<ul style={{ height: 200, overflow: `auto` }} {...ulScrollRestoration}>
{countryList.map(country => (
<li>{country}</li>
))}
</ul>
)
}
So, in your destination component (/aboutme/ page), use the useScrollRestoration hook in your outer wrapper to restore the scroll position.

how change background color in different pages

i am two page in reactjs
pageOne.js:
import React from "react";
import { Link } from "react-router-dom";
import "./pageOne.css";
const PageOne = () => {
return (
<div>
one
<br />
<Link to="/pageTwo">Two Page</Link>
</div>
);
};
export default PageOne;
pageTwo.js:
import React from "react";
import { Link } from "react-router-dom";
import "./pageTwo.css";
const PageTwo = () => {
return (
<div>
two
<br />
<Link to="/">One Page</Link>
</div>
);
};
export default PageTwo;
i am define two css files for change background color when page loaded.
pageOne.css
body {
background-color: whitesmoke !important;
}
pageTwo.css
body {
background-color: crimson !important;
}
it's problem.in pageOne background color is crimson and in pageTwo background color is crimson.
sample
As I said earlier, there is only one body tag in the DOM tree by default. So when you try to style it whatever comes last will override the previous ones and in your case, the page two style will override the page one style.
To solve this, you got several options, but I will go with the easiest one. You can make a container for each of your pages and then assign a colour to that container to make the whole page background as you desired (You can simply make a layout component then wrap each of the components within it and with similar approach make it reusable). So, for example, you can create your first page like this:
<div className="crimson">
two
<br />
<Link to="/">one Page</Link>
</div>
and style it like this:
.crimson {
background-color: crimson;
min-height: 100vh; /* minimum height of page would be equal to available view-port height */
}
This goes the same for your other page. But you need to consider you have to remove the default margins from the body itself to prevent any disorder.
Working Demo:
I would solve this with Layout component:
const Layout = ({ backgroundColor = '#fff', children }) => (
<div style={{ backgroundColor }} className="layout">
{children}
</div>
)
then remove your css(and try not to use important in your css)
<Layout backgroundColor="#fff"><PageOne /></Layout>
and
<Layout backgroundColor="#f00"><PageTwo /></Layout>

react-icons and react Router

Context
i'm designing a navigation bar for my application and my proyect uses react-router and react-router-dom for managing routing and react-icons for icon retrieving.
Code
import React from 'react';
import { NavLink } from 'react-router-dom';
import { MdAssessment } from 'react-icons/md'
import Styles from './NavBar.module.css'
const NavBar = (props) => {
return (
<nav className={Styles.navBar}>
{navIcon}
<NavLink
activeStyle={{ color : 'red' }}
className={`${Styles.navBar__Dashboard} `}
exact to="/">
<MdAssessment />
</NavLink>
<NavLink
activeStyle={{ color: 'red' }}
className={Styles.navBar__Requests}
to="/requests">
Requests
</NavLink>
<NavLink
activeStyle={{ color: 'red' }}
className={Styles.navBar__Tasks}
to="/tasks">
Tasks
</NavLink>
</nav>
)
}
export default NavBar
Problem
I'm trying to extrapolate activeStyle functionality of NavLink to my icon.
Given that react-icons provides you with component as icons, i'm struggling with which approach should i use:
Should i wrapped in a HOC?
Should i encapsulate in a custom Hook?
Notes
I've tried with both approaches but can't get my head arround it. I've tried implementing useRef, useEffect while reading to location with useLocation hook as well.
Any suggestion for a better implementation of a generic NavIcon feature taking this context into account?
By using curly brackets you are importing the icon as a named import. So the import only works if the file contains a named export of the same name you have assigned it. See this question for more info.
According to the package documentation, this is the correct way to import an icon. Can you check to make sure the named export is the same as you have imported?

Importing Ant Design Component doesn't work

I'm shocked over this problem I'm currently having right now. All my logic literally stopped. Something started not working, without me having changed anything. I mean I even have it on production, the identical code, but locally it started not working, out of nothing. Even when I go back to previous commits, that I'm 100% sure was working, it doesn't work.
Meteor, React, Ant-Design. Please help!
The error is: ReferenceError: Layout is not defined
Code is:
import React from 'react';
import Blaze from 'meteor/gadicc:blaze-react-component';
import { Link } from 'react-router-dom';
import { Layout, Menu } from 'antd';
const { Header, Content, Footer } = Layout;
class LayoutContainer extends React.Component {
render() {
const { match, children } = this.props;
const pathname = match.location.pathname;
return (
<Layout className="layout">
<Header style={{backgroundColor: '#fff'}}>
<Menu
selectedKeys={[pathname]}
mode="horizontal"
style={{ lineHeight: '64px', float: 'right' }}
>
<Menu.Item key={'/'}>
<Link to="/">Home</Link>
</Menu.Item>
<Menu.Item key={'/create-a-gathering'}>
<Link to="/create-a-gathering">Create</Link>
</Menu.Item>
</Menu>
<div className="logo" />
<Blaze template="loginButtons" />
</Header>
<Content style={{ marginTop: 20 }}>
{children}
</Content>
<Footer style={{ textAlign: 'center' }}>
</Footer>
</Layout>
)
}
}
export default LayoutContainer;
this is a reported antd issue here Reference Error: Layout not defined
an easy way to solve this is importing layout like this
import Layout from 'antd/lib/layout'
or you can also sort it out by updating antd version to "^3.2.2" or up
I should have answered this long time ago, but here it goes:
As Afaq Ahmed Khan pointed out (that too) :
import { Layout, Menu } from 'antd/lib';
is the answer.
I guess babel in two packages conflict with each other and thus '/lib' to root '/' alias doesn't work.
That can be resolved by deleting node-modules folder then rebuilding the whole project.

how to scale (large) font-awesome icons from the react-icons package

I am using the marvelouse react-icons package (http://gorangajic.github.io/react-icons/fa.html), specifically the font awesome package.
If this was not react, then I would just add an attribute to the tag, such as:
<i class="fa fa-camera-retro fa-5x"></i>
However, if I add the fa-5x to the FaFolderOpen tag, it does not do anything. As you can see, I am using react-bootstrap, and placing the icon a button (should it be a block)?
I have to believe this has been asked before, but I did not find it via search.
Here is what it looks like, and I want it larger:
const React = require('react')
import { Form, FormControl, FormGroup, ControlLabel, Col, Button, Tooltip, OverlayTrigger } from 'react-bootstrap'
import FaFolderOpen from 'react-icons/lib/fa/folder-open'
import FaFileCodeO from 'react-icons/lib/fa/file-code-o'
import FaFolderOpen from 'react-icons/lib/fa/folder-open'
import FaFileCodeO from 'react-icons/lib/fa/file-code-o'
<Button type="button" bsStyle="success" block onClick={(e) => folderChooser(e)}>
<FaFolderOpen />
</Button>
if you want a 5x icon size you need to pass it to the react class as size
// Font awesome pixel sizes relative to the multiplier.
// 1x - 14px
// 2x - 28px
// 3x - 42px
// 4x - 56px
// 5x - 70px
<FaFolderOpen size={70} />
if you notice it jumps by 14 each time
from the github readme it shows everything is overridden inline. its rendering a svg so you cant use 5x you have to use a pixel size
Edit
Coming back to this a few years later, with newer versions of FontAwesome/ReactIcons the recommended way to handle different sizings is with their icon provider that utilizes the React Context API. This requires React v16.3+
import { IconContext } from "react-icons";
<IconContext.Provider value={{ className: "shared-class", size: 70 }}>
<>
<FaFolder />
<FaBeer />
</>
</IconContext.Provider>
In reactjs you can use size = 'with your preferred size which be from sm to lg or 1x to 10x'
this is example for font awesome 5 in react
<FontAwesomeIcon icon={faBars} size = '10x'/>
If you need to style several icons simultaneously, you can wrap them to IconContext.Provider.
<IconContext.Provider value={{color: 'navy', size: 42}}>
<FaFacebook />
<FaGithub />
<FaLinkedin />
</IconContext.Provider>
An approach that is not very explicitly comes from docs (close to #Raimo Haikari):
App.jsx
import {IconContext} from "react-icons";
import { FaBeer } from 'react-icons/fa';
import './App.css'
class App extends component {
return (
<div>
<IconContext.Provider value={{ className="myReact-icons"}}>
<FaBeer />
</IconContext.Provider>
</div>);
}
App.css
.myreact-icons {
color: red;
height: 2em;
}
The default size is 1em. You can change it like this:
import { FcSurvey } from 'react-icons/fc';
<FcSurvey size={'2em'} />
Just to complement, because I was able to do it differently, you can also use the CSS property font-size or fontSize in JSON notation.
Using CSS in external file :
/* style.css */
.bigIcon {
font-size: 25px;
}
// index.jsx
import { FiPackage } from 'react-icons/fi';
import './style.css';
(...)
<FiPackage className="bigIcon" />
or (JSON syntax)
// index.jsx
import { FiPackage } from 'react-icons/fi';
(...)
<FiPackage style={{fontSize:'25px'}} />
I have a designer giving me pixel sizes that don't always correspond to one of FontAwesome's size options. So I'm setting the CSS height.
<FontAwesomeIcon icon={faBars} style={{ height: "20px" }} />
React-Icons has a prop called size that can be used to set to any size you want.
after importing the react-icon from the react-icon library, you can easily do something like this.
<FaUsers size={'4rem'} />
You can use this:
<FaFolderOpen size="4x" />

Resources