how to execute a .js file containing multiple functions, via react jsx - javascript

i have a pre-existing .js file which contains multiple functions ( they call each other within the file) and event listeners.
How do i execute this .js file after elements have been rendered in the .jsx ?
I have tried adding export statement to the bottom of the .js file
export const A = functionOne();
export const B = functionTwo();
and adding import
import {A} from './index'
in the .jsx file
but it still gives react error that functions are not defined.
I know the file with the functions works perfectly because previously it was being used in a basic html / .js combination to render the page elements.By using at the bottom of the html

Use exports.funcName. I have called them in useEffect hook
CodeSandBox Link
App.js
import React, { useEffect } from "react";
import "./styles.css";
import { funA, funB } from "./functions";
export default function App() {
useEffect(() => {
funA();
funB();
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
</div>
);
}
Functions.js
exports.funA = () => {
console.log("This is from Function A");
};
exports.funB = () => {
console.log("This is from Function B");
};

Related

Is there a way to import a function using Next.js dynamic import? react-component-export-image issues with Next.js ssr

I was getting the 'window is not defined' error when importing react-component-export-image so I used a dynamic import to get around that. I don't get that error anymore but now I get 'exportComponentAsPNG(componentRef) is not a function'. Is there a better way to deal with the 'window is not defined' error or a way to use the function I am importing dynamically? If not, is there a different npm library that works to generate an image from a react component?
import React, { useRef } from 'react'
// import { exportComponentAsPNG } from 'react-component-export-image' *This gave window not defined error so I used dynamic import*
import dynamic from 'next/dynamic'
import ProductCard from '../ProductCard/ProductCard.component'
import Button from '../Button/Button.component'
const { exportComponentAsPNG } = dynamic(
() => import('react-component-export-image'),
{
ssr: false
}
)
const Plaque = () => {
const componentRef = useRef()
// eslint-disable-next-line react/display-name
const ComponentToPrint = React.forwardRef((props, ref) => {
return (
<div ref={ref}>
<ProductCard />
</div>
)
})
return (
<ComponentToPrint ref={componentRef} />
<button onClick={() => exportComponentAsPNG(componentRef)}> // "Error: exportComponentAsPNG is not a function"
Export As PNG
</button>
)
}
export default Plaque
next/dynamic is used to dynamically import React components, not regular JavaScript functions or libraries.
For that, you can use a regular dynamic import on exportComponentAsPNG inside the onClick callback.
<button onClick={async () => {
const { exportComponentAsPNG } = await import('react-component-export-image')
exportComponentAsPNG(componentRef)
}}>
The exportComponentAsPNG function needs access to window which is undefined with server side rendering. I was able to fix the issue by dynamically importing the Plaque component that used exportComponentAsPNG to the page where it is called with sever side rendering set to 'false'.
import dynamic from 'next/dynamic'
const Plaque = dynamic(() => import('../compnonents/Plaque'), {
ssr: false
})
const Page = () => {
return <Plaque />
}
export default Page
Now that the component is no longer using SSR I was able to import and use the function normally.
import { exportComponentAsPNG } from 'react-component-export-image'
Here you can find the documentation for the library: https://www.npmjs.com/package/react-component-export-image

How to use vanta with nextjs?

I am trying to use vanta with next.js, following this guide. It works completely fine with the Net Effect, however, when I try to use the Globe Effect, I get
[VANTA] Init error TypeError: r.Geometry is not a constructor
at h.onInit (vanta.globe.min.js:1)
at h.init (vanta.globe.min.js:1)
at new r.VantaBase (vanta.globe.min.js:1)
at new h (vanta.globe.min.js:1)
at r.<computed> (vanta.globe.min.js:1)
I have isolated Vanta into an Background Component
//Background.js
import { useState, useRef, useEffect } from "react";
import NET from "vanta/dist/vanta.globe.min"
import * as THREE from "three";
export default function Background({ width, height, children }) {
const [vantaEffect, setVantaEffect] = useState(0);
const vantaRef = useRef(null);
useEffect(() => {
if (!vantaEffect) {
setVantaEffect(
NET({
THREE,
el: vantaRef.current,
})
);
}
return () => {
if (vantaEffect) vantaEffect.destroy();
};
}, [vantaEffect]);
return (
<div ref={vantaRef}>{children}</div>
)
}
And added the THREE script into my _app.js
import '../styles/globals.css'
import Head from "next/head";
import Navbar from "../components/Navbar";
import { useEffect } from "react";
export default function App({ Component, pageProps }) {
useEffect(() => {
const threeScript = document.createElement("script");
threeScript.setAttribute("id", "threeScript");
threeScript.setAttribute(
"src",
"https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"
);
document.getElementsByTagName("head")[0].appendChild(threeScript);
return () => {
if (threeScript) {
threeScript.remove();
}
};
}, []);
return (
<>
<Head>
<title>BrainStorm Tutoring</title>
</Head>
<Navbar />
<Component {...pageProps} />
</>
)
}
and used it like so
//index
import Background from "../components/Background";
export default function Home() {
return (
<Background height="400" width="400">
<h1 className="text-white text-8xl text-left p-36">Fish Bowl</h1>
</Background >
)
}
Is it something wrong with THREE, or is it that next.js can't support vanta?
I have that issue with Halo, so i think the THREE object was not available or was not defined in the HALO.js file.
So i go to the official github repo of Vanta and take the source of Halo and Net (the tutorial effect) file, and i found constructor was missing in the Halo file. So i take the one of Net and put in the Halo file.
constructor(userOptions) {
THREE = userOptions.THREE || THREE;
super(userOptions);
}
Then i import my custom Halo file for the effect and it works.
I was playing around with this and found that, if I keep the Three.js version to 122. I don't get the error. Apparently any version after that has a breaking change.

Run a Script in React JS/TSX file

I have a ReactJs file, Component.js and I want to execute a Script which looks like this:
<script type='text/javascript'>
window.onAmazonLoginReady = function() {
amazon.Login.setClientId('CLIENT-ID');
};
window.onAmazonPaymentsReady = function() {
//Will also add this button implementation method
showButton();
};
</script>
I want to include this Script in Component.js file, but couldn't think of any way. I had included this in index.js/index.html but I want the above script to be executed when the Component.js file loads.
This is my component.js file:
import React, { useContext, Component } from 'react';
import { Link } from 'react-router-dom';
const Component = () => {
return (
<div> Hello from Component </div>
);
};
export default Component;
You can just add the script inside the useEffect of the Component.js file like this :
useEffect(() => {
const setLoginClientId = () => {
amazon.Login.setClientId('CLIENT-ID');
};
// If this "onAmazonLoginReady" is a javascript event then you should add like this
// window.addEventListener("onAmazonLoginReady",setLoginClientId);
window.onAmazonLoginReady = setLoginClientId;
// Removed the unncessary function inside function,
// you can directly call showButton now
window.onAmazonPaymentsReady = showButton;
//Calling Set Client Id once, if you want
setLoginClientId();
},[]);
This will only run one time just after the Component loads.

Having Trouble Accessing Function in Adjacent JS file

Currently in my directory I have App.js and startMenu.js as two separate files.
I would like to access startMenu.js in my App.js file with the correct React formatting.
Currently I can call the function startMenu() using typical javascript syntax, but I for some reason cannot get the React syntax {startMenu} to work. Any ideas would be appreciated.
My code:
import React from "react";
import startMenu from './startMenu';
import credits from "./credits";
var param = 'start';
class App extends React.Component {
renderSwitch(param) {
switch(param) {
case 'credits':
return credits();
default:
/*LINE IN QUESTION */
return startMenu();
}
}
render() {
return (
<div>
{this.renderSwitch(param)}
</div>
);
}
}
export default App;
Thanks!
It is depending how you are exporting your function.
If is doing this:
export default startMenu;
Then you might import that way:
import myFunction from './path';
That way the name does it care. You can call your function with any name when you are exporting by default.
But if you are exporting that way:
export { startMenu };
or
export startMenu;
So than you need import your function by your reall name, and if you are exporting just using export word, all members will be inside an object.
So you need do that:
import MyFunctions from './path';
or doing a import destruction
import { startMenu } from './path';
You'll need to properly export that function:
export function startMenu(...) { ... }
Then import it:
import { startMenu } from './startMenu';
If that's the only thing exported you can always export default and it simplifies the import.
You can only import things that have been exported. Everything else is considered private and is off-limits.
The JSX syntax: {foo} means "Put this data here".
It doesn't mean "Call this variable as a function".
If you want to call it, you need to do so explicitly: {foo()}.

Exporting functions with reactjs and babel

I have a project using reactjs, which is transpiled by babel. I use the es2015 and react transforms in my .babelrc. I am currently refactoring and in my first pass I basically did export class foo for everything I needed. A lot of these classes should really just be functions, so I am trying to rewrite them as such, but I keep getting the same error. My main application file looks somethings like this:
import React, { Component } from 'react';
import {Foo, Bar} from './components/ui.js';
class Application extends Component {
constructor(props){
super(props);
this.state = {
object: null
}
}
componentDidMount(){
// code
}
componentDidUpdate(){
// other code
}
render(){
return(
<div>
<Foo />
<Bar />
</div>
)
}
}
module.exports = Application
And my import from ui.js is like this:
import React, { Component } from 'react';
export class Foo extends Component {
constructor(props){
super(props);
}
render() {
return (
// Some JSX
)
}
}
export class Bar extends Component {
constructor(props){
super(props);
}
render() {
return (
// Some other JSX
)
}
}
When I try and change one of these exported classes to a function, for example:
// Note: I have tried a variety of syntax such as function, const, etc...
export var Bar {
render() {
return (
// Some other JSX
)
}
}
I get the following error:
SyntaxError: Unexpected token <line where I declare a function>
I am not sure what I am doing wrong, and my google searches are only coming up with answers to other problems.
It's the same as defining the function as a variable but just adding export to the front e.g. (using ES6 syntax)
export const render = () => (
// Some other JSX
);
or alternatively
export var render = function() {
return (
// Some other JSX
);
};
Exporting functions is no different than exporting class. Basic rules must be followed .
Function/Class name should in CAPS
There will be only one "export" line .
Every function return body should have a single tag encompassing other parts. Most commonly used is a tag .
This usually works: import App from "./App"; where App.js is my jsx file.
You can do an explicit import too . : import AllApp from "./classhouse.jsx";
Name of the js/jsx file does not matter. It can be anycase (lower, upper).
For returning multiple functions from one file, you need to create one more function , that encompasses all other functions .
See the example below showing multiple functions returned.
import React from 'react';
/* All function / class names HAS TO BE in CAPS */
var App1 = function (){
return (
<div>
<h1>
Hello World
</h1>
</div>
)
}
var App2 = function (){
return (
<div>
<h1>World Number 2 </h1>
</div>
);
}
var AllApp = function (){
return (
<div>
<App1 />
<App2 />
</div>
);
}
export default AllApp;
My index.js file:
import React from 'react';
import ReactDOM from "react-dom";
import AllApp from "./classhouse.jsx"; /* Note: App name has to be in CAPS */
import App from "./App";
const jsx =
<div>
<AllApp />
<App />
</div>
ReactDOM.render(jsx, document.getElementById("root"));
You are writing functional components in wrong way.
function Welcome() {
return <h1>Hello World</h1>;
}
or
const Welcome = () => {
return <p>Hello Wrold</p>
}
export default Welcome ;
ES6 doesn't allow export default const. You must declare the constant first then export it.

Categories

Resources