Use NPM package in React Component - reactjs

I try to use Pannellum NPM package in my React component.
Pannellum's API can be used like this:
pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
I thought the following code:
import React, { Component } from 'react';
import './App.css';
import pannellum from 'pannellum';
class App extends Component {
componentDidMount() {
pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}
render() {
return (
<div id="panorama"></div>
);
}
}
export default App;
would work. However it does not. I get TypeError: __WEBPACK_IMPORTED_MODULE_2_pannellum___default.a.viewer is not a function.
Tried also a different import statements:
import { pannellum } from 'pannellum';, const pannellum = require('pannellum'); but these also don't work.
What's interesting, Pannellum's API javascript code is bundled and once I comment out componentDidMount() and try to use the API via Chrome Dev Tools console once the page is loaded, it works. However there are no CSS styles applied.
I clearly do something wrong.
I have seen 360-react-pannellum package source code but I need access to the whole API, not just rendering so it does not suit my needs.
Thank you for your help.

Looking at the source code of pannellum, it does not export any module but puts everything on the window object.
Try importing the code and using it directly from the window.
import React, { Component } from 'react';
import './App.css';
import 'pannellum';
class App extends Component {
componentDidMount() {
window.pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}
render() {
return (
<div id="panorama"></div>
);
}
}
export default App;

Try
componentDidMount() {
window.pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}

Related

React unit test getting TypeError: Cannot read properties of undefined (reading 'Component')

I'm new to React and React unit testing. I'm trying to create a simple test and am getting the following error: "TypeError: Cannot read properties of undefined (reading 'Component')" Here's my code.
HelloWorld.js
import React from "react";
class HelloWorld extends Component {
render() {
return ( < h1 > My First ReactJS Core App! < /h1>);
}
}
export default HelloWorld
test.js
import React from "react";
import {
HelloWorld
} from "../wwwroot/src/react/HelloWorld"
import {
render,
screen
} from "#testing-library/react";
describe("apptest", () => {
it("works", () => {
render( < HelloWorld / > );
screen.getByText("My First ReactJS Core App!");
});
});
When I run "npm test", I get the following:
What am I doing wrong?
When I see your code, you don't have Component importing, but the error message shows React.Component.
Does your original code match with your attached code?
If it is, please try to add the following import.
import React, {Component} from 'react'
check this
import React, { Component } from "react";
class Temp extends Component {
render() {
return <h1> My First ReactJS Core App! </h1>;
}
}
export default Temp;
import { render, screen } from "#testing-library/react";
import Temp from "./Temp";
describe("apptest", () => {
it("works", () => {
render(<Temp />);
screen.getByText("My First ReactJS Core App!");
});
});
I had my original code in a .jsx file. The code got transpiled to a .js file which I was referencing in my test. Again, I don't know much about transpiling but when I created a new js file and imported that, the test passed.

I'm upgrade material-ui to v4, It doesn't work properly and throw errors, What caused it?

When I upgrade v4, I get errors:
Uncaught (in promise) Invariant Violation: You must pass a component to the function returned by connect. Instead received {"propTypes":{},"displayName":"WithStyles(EditDialog)",...}
I tried to view the version of react-redux according to the I'm getting error after upgrading to Material UI 4 - withStyles method:
$ npm view react-redux version
7.1.0
Obviously, our situation is different.
It should be noted that my project is written using class component, so maybe this is the reason?
Is there any way to help me locate the problem?
----- Apend --------------
I'm use umi framework, And this is my code:
account/index.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
import DetailDialog from './components/DetailDialog';
import EditDialog from './components/EditDialog';
class Index extends React.Component {
...
}
function mapStateToProps(state) {
const { list } = state.account;
return {
list
};
}
export default connect(mapStateToProps)(withStyles(styles)(Index));
account/components/DetailDialog.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
class DetailDialog extends React.Component {
...
}
DetailDialog.propTypes = {
open: PropTypes.bool,
...
};
function mapStateToProps(state) {
const { list } = state.account;
return {
list
};
}
export default connect(mapStateToProps)(withStyles(styles)(DetailDialog));
account/components/EditDialog.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
class EditDialog extends React.Component {
...
}
EditDialog.propTypes = {
open: PropTypes.bool.isRequired,
};
EditDialog.defaultProps = {
open: false,
};
function mapStateToProps(state) {
const { list} = state.account;
return {
list,
};
}
export default connect(mapStateToProps)(withStyles(styles)(EditDialog));
#/utils/pageLayout.js
const styles = theme => ({
r: {
height: '100%',
},
...
});
export default styles;
I see that you are importing connect from 'dva'. Unless you are using a beta version, the latest version of dva is 2.4.1 which includes react-redux as a dependency (not a peer dependency) and it is using "react-redux": "5.0.7". This will then have the exact same problem as the question you linked to.
This means you probably have two versions of react-redux in play (and likely two versions of redux as well), one included directly in your own package.json and one pulled in by dva.
Your main options would be to upgrade dva to its most recent beta version (currently 2.6.0-beta.12) or import connect from react-redux instead of dva.
I don't know anything about dva, so I have no idea what shape the beta is in, but given that it is the 12th beta, I would guess it is pretty close to a stable release.
If you are consistently importing redux/react-redux pieces from dva, then you may want to consider removing react-redux and redux from your own package.json to avoid duplicating them with different versions.

I don't get why my component is called twice in this example

I've been following the complete react native and redux guide on Udemy and there is this part where despite following down to a tee. My LibraryList component still gets called twice.
What could be the problem?
LibraryList.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
class LibraryList extends Component {
render() {
console.log(this.props);
return;
}
}
function mapStateToProps(state) {
return {
libraries: state.libraries
};
}
export default connect(mapStateToProps)(LibraryList);
App.js
import React from 'react';
import { View } from 'react-native';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from './reducers';
import { Header } from './components/common';
import LibraryList from './components/LibraryList';
const App = () => {
return (
<Provider store={createStore(reducers)}>
<View>
<Header headerText='Tech Stack' />
<LibraryList />
</View>
</Provider>
);
};
export default App;
LibraryReducer.js
import data from './LibraryList.json';
export default () => data;
index.js inside reducers folder
import { combineReducers } from 'redux';
import LibraryReducer from './LibraryReducer';
export default combineReducers({
libraries: LibraryReducer
});
LibraryList.json
[
{"id": 0,
"title": "Webpack",
"description": "Webpack is a module bundler. It packs CommonJs/AMD modules i. e. for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand."
},
....
]
Expected result: console.log(this.props) runs once and return libraries
Actual result: It runs twice
I had a similar problem with one of my projects.
In LibraryList.js instead of extending Component use PureComponent. PureComponents won't call the render function if the state and the props have not changed, since it integrates a simple check in the shouldComponentUpdate method. https://reactjs.org/docs/react-api.html#reactpurecomponent
You could always implements your own shouldComponentUpdate method with a React Component instead of using the PureComponent. You'll need to be careful when implement the shouldComponentUpdate method with Redux, you may create more bugs. https://redux.js.org/faq/react-redux#why-isn-t-my-component-re-rendering-or-my-mapstatetoprops-running
When I tried your example on Android and iOS, I wasn't able to replicate your issue, it only returned once.

error in displaying pdf in react-pdf

I am new new to react, I am trying to display a pdf file on browser. I am getting an error as failed to load PDF. I am trying to run the sample program given in https://www.npmjs.com/package/react-pdf.
App.js
import React, { Component } from 'react';
import { Document, Page } from 'react-pdf';
class MyApp extends Component {
state = {
numPages: null,
pageNumber: 1,
}
onDocumentLoad = ({ numPages }) => {
this.setState({ numPages });
}
render() {
const { pageNumber, numPages } = this.state;
return (
<div>
<Document
file="./1.pdf"
onLoadSuccess={this.onDocumentLoad}
>
<Page pageNumber={pageNumber} />
</Document>
</div>
);
}
}
export default MyApp;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Error screenshot
Question is old but hope this help someone. I faced this issue and found a solution here https://github.com/wojtekmaj/react-pdf/issues/321.
import { Document, Page, pdfjs } from 'react-pdf';
Add this to your constructor.
constructor(props){
super(props);
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
}
You load the file using file="./1.pdf" I believe that might be the problem.
If you have a file structure like:
src
App.js
components
ShowPdfComponent.js
1.pdf
public
bundle.js
Then you need to move the 1.pdf to public folder like this:
src
App.js
components
ShowPdfComponent.js
public
bundle.js
1.pdf
Because when your compiled javascript code is being executed from public/bundle.js and bundle.js does not know how to get to src/components/1.pdf in file system.
There might be also a difference between production/development environment if you are using webpack and webpack-dev-server.
Look at react-pdf example. It has flat file structure. That is the reason why it works.
if you are using create-react-app then you need to import differently like
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'
because it uses webpack under the hood.
You can import the pdf file using import samplePdf from './1.pdf' and can use directly like file={samplePdf} in your Document tag.
Here is the minimum setup you need to be able to display your pdf in react TypeScript:
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
const YourComponentReact = ({url}: {url: string}) => {
return (<Document file={url}>
<Page pageNumber={1} />
</Document>)
}
You can add a quick button if you want to be able to change pages
You only need to download react-pdf and #types/react-pdf if you use typescript.
adding pdfjs to import and using it like this hellped
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
in the same file i need to show my pdf

Using marked in react

I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview

Resources