Working on a application which uses NextJS. Having the following problem. When I have a _document file like this:
import Document, { Head, Main, NextScript } from 'next/document';
import Header from '../components/header/header';
export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
</Head>
<body>
<Header /> // Header is custom component
<Main />
<NextScript />
</body>
</html>
)
}
}
And my Header component is as follows:
import React, { Component } from 'react';
import { withRouter } from 'next/router';
import Link from 'next/link';
class navigationMobile extends Component {
render() {
return (
<nav>
<Link href="/auth"><a>Auth</a></Link>
</nav>
);
}
}
export default withRouter(navigationMobile);
Because this link is placed outside of the file it will reload the page for some reason. This will lose the application state and ruin UX and kind off defeats the purpose of implementing something with a SPA.
When I place the Header component in a page itself the routing works fine. The problem however is that I would have to put this component in every page.
Question:
Is there a way to not reload the page and still have the header component only in one place of the application?
You can use a custom _app.js. This is the correct place where to put a custom layout.
https://github.com/zeit/next.js/tree/master#custom-app
Related
I have a NextJS application where a third party script is only needed on certain pages. Currently it is firing on all pages, but this is causing some issues.
It's currently added after the closing body tag via a custom _document.js file. As the script has to go in the body, I can't use the head option in NextJS.
What would be the best way to only have this fire on a specific page template?
import { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';
export default function Document() {
return (
<Html>
<Head></Head>
<body>
<Main />
<NextScript />
{/** Below script only needed on certain pages */}
<script
src="xxx"
id="widget"
/>
</body>
</Html>
)
}
You should probably do this in _app.js instead:
import Script from 'next/script'
const allowedPages = new Set([...]);
export default function MyApp({ Component, pageProps }) {
const { asPath } = useRouter();
const enableScript = allowedPages.has(asPath);
return (
<>
<Component {...pageProps} />
{enableScript && <Script id="widget" src="xxx" />}
</>
)
}
Because you'll have access to useRouter and it will update on every page navigation. _document.js is only used on the first SSR
I am trying to use the import keyword in a .jsx file in my ASP.NET MVC 5 project. I want to be able to import other React components into another React component, however, when using the import keyword, I am getting the following error:
Uncaught SyntaxError: Cannot use import statement outside a module
Below is my code:
Index.cshtml:
#{
Layout = null;
}
<html>
<head>
<title>Hello React</title>
</head>
<body>
<div id="content"></div>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.development.js"></script>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js"></script>
<script src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
</body>
</html>
Tutorial.jsx:
import Comment from '../Scripts/Comment.jsx';
class Tutorial extends React.Component {
render() {
return (
<div className="commentBox">
<h1>Homepage</h1>
<Comment />
</div>
);
}
}
ReactDOM.render(<Comment />, document.getElementById('content'));
Comment.jsx:
class Comment extends React.Component {
render() {
return (
<p>I am a comment!</p>
);
}
}
export default Comment;
If I do not have the imports or if I add the Comment class directly inside of the Tutorial.jsx, it runs fine, but that is not what I am looking for. I want to be able to have all my components in separate .jsx files and be able to import certain components into different ones. Ideas?
EDIT: Fixed export default Comment, however error is still appearing
The error "Cannot use import statement outside a module" results when a <script> element contains an import statement but the <script> element itself is not declared as an ECMAScript (or ES) module.
The import statement requires your script file Tutorial.jsx to be declared a module. Add the type attribute with the value module to the <script> tag.
See the first paragraph at the top of the page https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
The import statement cannot be used in embedded scripts unless such script has a type="module".
In your HTML page, change:
<script src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
to
<script type="module" src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
You need to export the Comment component properly. At the moment you are doing export default Test.
class Comment extends React.Component {
render() {
return (
<p>I am a comment!</p>
);
}
}
export default Comment; //<------- see here
I'm trying to embed a tlk.io chat widget on my Gatsby site since no similar plugins seem to exist. I'm using the react-helmet plugin to embed that script, but nothing shows up on my page. My code you can find below.
I think it has to do with the fact that the script relies on this data-channel attribute in the div tag, but I have no idea what to do with regards to that.
import React from "react"
import Helmet from "react-helmet"
import Layout from "../components/layout"
import SEO from "../components/seo"
const LivePage = () => (
<Layout>
<SEO title="Live" />
<Helmet>
<div id="tlkio"
data-channel="hey"
style={{width:'auto',
height:400}}></div>
<script src="http://tlk.io/embed.js" type="text/javascript"></script>
</Helmet>
</Layout>
)
export default LivePage
According to Gatsby documentation about Helmet, and React Helmet <Helmet> component allows you to insert a few code that will be placed after compilation inside the <head> tag.
So, in your code, you need to remove the <div> tag and it will work like a charm.
import React from "react"
import Helmet from "react-helmet"
import Layout from "../components/layout"
import SEO from "../components/seo"
const LivePage = () => (
<Layout>
<SEO title="Live" />
<Helmet>
<script src="https://tlk.io/embed.js" type="text/javascript"/>
</Helmet>
</Layout>
)
export default LivePage
I've tested in my local machine and it works perfectly as it is shown in the following screenshot:
React Helmet is a plugin that adds its children to head tag of your webpage. You cannot add div element to head, but instead inside body of the website. Just put that div somewhere outside Helmet and you should be fine.
How to use setInterval function in react to repeatedly render a function in react . Please provide a very simple example . I am using Node js local environment. Here I am trying for a simple clock given in react documentation (but mine file structure is different). I don't know about didMount etc.. Just starting.
Below is my App.jsx
import React,{ Component } from 'react';
class App extends Component {
good(){
{new Date().toLocaleTimeString()}
}
render() {
return (
<p>{setInterval(()=>this.good(),500)}</p>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />, document.getElementById('app'));
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
My folder structure is like below
I suggest you to read more about React components, state and props as these are fundamental parts for which you have chosen to use React in first place. Basic steps would be:
Store time as state of your component.
Start ticking functionality as soon as your component loads (that is what componentDidMount does - it's triggered when component loads in page)
On each tick use setState to change time value (setState triggers render)
If you follow these steps you would achieve similar result to example from React site, and this is how it should really be done (if you really want to do it in React design)
This is embarrassing but I am losing time trying to figure out why a reactjs component isn't rendering.
Here is the code I have currently:
// index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ulonka Frontend</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
</body>
</html>
In routes.js
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, browserHistory, IndexRoute } from 'react-router'
import App from './App'
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
</Route>
</Router>
), document.getElementById('app'))
in App.js
import React from 'react'
export default React.createClass({
render() {
return <div> <h1> Hello </h1> </div>
}
})
Checked sources in dev tools and can see the string 'Hello' in bundle.js but for some reason it won't display in browser.
Can someone please explain to me what I am missing? Would greatly appreciate help. Thanks!
#Ursus, #polkovnikov.ph, #TheReason!
Forgot to indict that I figured out what my error was.
My error was setting the root component of the app (App.js) to the entry point of the App (index.js). Once that was mistake was corrected, App.js was rendered to the DOM.
Thanks for all your all; greatly appreciated.
You're using the wrong syntax in App.js: the class you want to export doesn't have a name.
So App.js should be either
import React from 'react'
const Hello = React.createClass({
render() {
return <div> <h1> Hello </h1> </div>
}
})
export default Hello;
or, ES6 version,
import React from 'react'
class Hello extends React.Component({
render() {
return <div> <h1> Hello </h1> </div>
}
})
export default Hello;
Check, for example: https://toddmotto.com/react-create-class-versus-component/
Your routes may be wrong. Your code works without react-router. Well, not quite: it works after applying the correct syntax. Check the fiddle.
Also, are routes.js and App.js in the same directory?
render method has been moved to react package.
Try this
import React, { render } from 'react'