Problem:
The Next JS dynamic import is stuck on loading on mobile device browser (used browser: Google Chrome and Safari on IOS.) Whereas it is working perfectly on Google Chrome and Mozilla on Desktop. I am also using next-PWA on the default configuration. Could it be due to next-PWA?
Code Snippet:
import dynamic from "next/dynamic";
import { useMemo } from "react";
export default function Main() {
const Component = useMemo(
() =>
dynamic(() => import("#components/Component"), {
loading: () => <p>The component is loading</p>,
ssr: false,
}),
[],
);
return(<div><Component/></div>);
}
Output on Mobile Device
The component is loading
Output on Desktop Browser
Hello from Component
The fault was not of the Next Dynamic rather than it was due to HTTP site not getting navigator resources in mobile browsers.
Related
It was my understanding that if I was to dynamically import the only components that use a third-party library, then that library wouldn't be included in the 'First Load Bundle' shipped out to the client.
I am using Recharts in the following two components (this is the only place it's imported in the app), and I am then importing those components into the parent component like this:
const UvGraphTile = dynamic(() => import("#/components/tiles/UvGraphTile"), {
ssr: false,
});
const StravaGraphTile = dynamic(() => import("#/components/tiles/StravaGraphTile"),
{
ssr: false,
}
);
However Recharts still appears in the 'First Load Bundle', as seen in the screen shot provided. I don't know if I am making a mistake, or if my interpretation of the dynamic import for NextJS is incorrect.
Any help would be greatly appreciated! :)
ReactJS and NextJS newbie here would appreciate any advice on below issue! Thanks!
The stack:
Node v16.6.1
React v17.0.2
Next.js v10.0.4
I am implementing a carousel, and--since carousel will need client-side javascript--am using next/dynamic to implement a dynamic component with no SSR. This works fine, but when I add a javascript event listener to the dynamic module, the module stops being rendered.
Debugging Next in Chrome DevTools shows no errors or warning when compiling the page. I couldn't find a reference to any additional compile information being available in Next documentation.
Parent module:
import react from 'react';
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/shared/dynamicTestComponent'),
{ ssr: false }
)
const TestEmbedDynamicComponent: React.FC = () => {
return (
<div>
<div>this is text above dynamic component</div>
<DynamicComponentWithNoSSR/>
<div>this is text below dynamic component</div>
</div>
)}
export default TestEmbedDynamicComponent
Dynamic module:
const selectedButton = document.querySelector(".selectMe");
//selectedButton.addEventListener("click", e => {alert("dynamic module loaded!");});
const DynamicTestComponent: React.FC = () => {
return (
<div className="">lorem ipsum
<button className="selectMe">clickMe!</button>
</div>
)}
export default DynamicTestComponent
Result:
And if I uncomment the line where the listener is added:
I see you use a named dynamic import with ssr: false - in my case i changed that to an import like: import { DynamicComponentWithNoSSR } from ''../components/shared/dynamicTestComponent''; (and comment out or delete dynamic in parent).
After that change all event listeners started to work. Also for imported elements and stuff.
I have an 'external' intl provider because I have to handle some labels outside react components.
I am trying to dynamically load the locales without using require statements and I am having a issue I am not sure why it's happening.
So, the following code works:
//intlProvider.js
import { IntlProvider, addLocaleData } from 'react-intl';
import Locale from '../../../../utils/locale';
const locale = Locale.getLocale();
addLocaleData(require(`react-intl/locale-data/${locale}`));
const messages = Locale.getMessages('prot');
const intlProvider = new IntlProvider({ locale, messages });
const { intl } = intlProvider.getChildContext();
export default intl;
then I read the intl in a sharedMessages.js file:
import { defineMessages } from 'react-intl';
import intl from '../components/i18n/Intl';
const messages = defineMessages({
interest: {
id: 'sharedMessages.rate.label',
defaultMessage: 'Interest',
},
bank: {
id: 'sharedMessages.bank.label',
defaultMessage: 'Bank',
},
});
function prepareSharedMessages() {
const msgsObj = {};
Object.keys(messages).forEach(item => {
msgsObj[item] = intl.formatMessage(messages[item]);
});
return msgsObj;
}
const sharedMessages = prepareSharedMessages();
export default sharedMessages;
The above code works fine, but since I want to get rid of the require statement in this line (as dynamic imports increase the bundle a lot):
addLocaleData(require(`react-intl/locale-data/${locale}`));
I tryed to replace it for:
(async localeCode => {
const localeData = await import(`react-intl/locale-data/${localeCode}`);
addLocaleData(localeData.default);
})(locale);
Expected behavior
I'd expect the locale to be loaded properly, but apparently the application is trying to get it before it should. Since I am using async/await, I'd expect it to be set before the rest of the application tries to use it. (If it was inside react components, I could use componentDidMount to trigger the locale, but how can I achieve this behavior for non react components?)
Current behavior
After replacing the require for the import statement above mentioned, I am getting the react-intl warning:
[React Intl] Missing locale data for locale: "de". Using default
locale: "en" as fallback.
My Environment:
react-intl 2.7.0
react 16.0.0
node 9.10.0
OS: macOS Mojave 10.14
Browser Version: Chrome 71.0.3578.98 (Official Build) (64-bit)
I've got a problem where my add-in is running fine in Outlook Online, but won't run in Outlook desktop. The add-in is successfully activated from the manifest, but fails after load. This is a React + TypeScript project (testing using NodeJS + webpack in Webstorm).
I've narrowed the problem to the usage of ANY require statement for importing a reference. If I eliminate it, it runs fine and shows my test Office UI Fabric CompoundButton component. With the code, it spins and eventually shows a blank page. No script exceptions are thrown, and this is enabled in IE settings.
Why would this fail only on the desktop?
To repro, use three files:
Start/main page: myapp.tsx
Which renders TestComponent.tsx
Which references test.jsx
//myapp.tsx
import TestComponent from './components/TestComponent';
import * as $ from 'jquery';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
const render = (Component) => {
ReactDOM.render(
,
document.getElementById('container')
);
};
Office.initialize = function () {
$(document).ready(function () {
console.log('====myapp.tsx.Office.initialize(): entered');
render(TestComponent);
});
};
if ((module as any).hot) {
console.log('====index.tsx.module() foo');
(module as any).hot.accept('./components/App', () => {
const NextApp = require('./components/App').default;
render(NextApp);
});
}
//TestComponent.tsx
import * as React from 'react';
import { CompoundButton } from 'office-ui-fabric-react/lib/Button';
//============
// BAD CODE!
//import foo = require('../scripts/test.jsx');
//============
export default class TestComponent extends React.Component {
render() {
console.log('====TestComponent.render()');
//============
// BAD CODE!
//foo.testFunction();
//============
return(
Create account
);
}
}
//test.jsx
export function testFunction(){
console.log("test.jsx: testFunction");
}
Office 2013 and 2016 for Windows (desktop apps) use an embedded IE 11 browser for rendering. IE 11 doesn't support a lot of the recent JS features you find in Edge, Chrome, and Firefox. As such, you either need to polyfill the functionality you need to provide alternative paths for IE 11.
One quick-fix may be just changing how TypeScript is generating JS so that it is compatible with IE 11:
{
"compilerOptions": {
"skipLibCheck": true,
"lib": [ "es5", "dom", "es2015.promise" ]
}
}
I was trying to have my connectors open up a component in a clean and easily readable way for Android & iOS platforms. To me this is using the component.android.js and component.ios.js extensions for things that are majorly different like tabs over slide-in drawer, etc.
Yes, I am aware of the Platform object I can create conditions on, however I really want to make this clean from an ES6 modules stand point and I don't think conditional import statements are clean or even possible.
'use strict'
import { connect } from 'react-redux';
import DashboardView from './DashboardView';
/* Mapping */
const mapStateToProps = state => {
return {
display: state.app.deviceInformation,
}
}
const mapDispatchToProps = (dispatch, props) => {
return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(DashboardView);
Again, what I want here is to have DashboardView automatically know that if in Android it should open DashboardView.android.js and on iOS obviously DashboardView.ios.js
That would be much cleaner to handle separate UI components... to me anyway.
I have just discovered the correct answer by accident. Figured it's worth documenting here.
I changed the DashboardView.android.js & DashboardView.ios.js file names to instead be index.android.js & index.ios.js
Works like a charm now, all is well.