Import JavaScript file and call functions using webpack, ES6, ReactJS - reactjs

Trying to do something I would think would be very simple. I would like to import an existing JavaScript library and then call it's functions. So for example I would like to import blah.js and then call blah().
import React from 'react';
import {blah} from 'blah/js/blah.js';
class MyClass extends React.Component {
constructor() {
super();
}
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize() {
blah.blah();
}
render() {
....
}
}
export default MyClass;
Just wondering what magical combination of things I have to do to make this work. Maybe I'm just missing the point. The example gives the error "TypeError: _blah.blah is undefined".

Named exports:
Let's say you create a file called utils.js, with utility functions that you want to make available for other modules (e.g. a React component). Then you would make each function a named export:
export function add(x, y) {
return x + y
}
export function mutiply(x, y) {
return x * y
}
Assuming that utils.js is located in the same directory as your React component, you can use its exports like this:
import { add, multiply } from './utils.js';
...
add(2, 3) // Can be called wherever in your component, and would return 5.
Or if you prefer, place the entire module's contents under a common namespace:
import * as utils from './utils.js';
...
utils.multiply(2,3)
Default exports:
If you on the other hand have a module that only does one thing (could be a React class, a normal function, a constant, or anything else) and want to make that thing available to others, you can use a default export. Let's say we have a file log.js, with only one function that logs out whatever argument it's called with:
export default function log(message) {
console.log(message);
}
This can now be used like this:
import log from './log.js';
...
log('test') // Would print 'test' in the console.
You don't have to call it log when you import it, you could actually call it whatever you want:
import logToConsole from './log.js';
...
logToConsole('test') // Would also print 'test' in the console.
Combined:
A module can have both a default export (max 1), and named exports (imported either one by one, or using * with an alias). React actually has this, consider:
import React, { Component, PropTypes } from 'react';

import * as utils from './utils.js';
If you do the above, you will be able to use functions in utils.js as
utils.someFunction()

Check out the working code here :
Link to the Netlify React App using Javascript :
https://paint0183.netlify.app/
Source Code of Microsoft Paint Clone:
Github Source Code
Faced the same problem but the answer was simple
why not import directly?
import {file-name} from "./file-path";
For example :
import {jscolor} from "./jscolor";
The only thing which you need to add to make sure the javascript loads after the DOM has loaded :
window.onload=function() {
// your entire javascript code here
}

Related

Issues with mock + multiple exports in the same file on react-testing-library

I am using Jest + React Testing Library in my project, and in one of my components, I have a common index.ts that exports all the internal components like:
src/components/commonComponents/index.ts:
import A, { IAProps as AType } from './components/A';
import B, { IBProps as BType } from './components/B';
import { C, commonFunc } from './components/Shared';
export type IAProps = AType;
export type IBProps = BType;
export { A, B, C, commonFunc };
And I have a component making use of that like:
src/mainComponent:
import { A, commonFunc } from 'components/commonComponents';
I am trying to test mainComponent, as can be seen on top, I need to import 2 of the components being exported in the same index.
I mocked all redux selectors so that, I wouldn't have issues with it. But for some reason the import on top, makes react-testing-library to give me an error on redux (a-if I missed mocking a function) on component B that I am not using anywhere and therefore also not mocking anything for that. But if I changed the above import to something like:
import A from 'components/commonComponents/components/A';
import { commonFunc } from 'components/commonComponents/components/Shared';
I don't get the error anymore...
Any idea what can I do? I can't change all my components to be imported directly from each main file since sometimes I wrap my component with HOC in the index, and they will be needed in future tests...

how to export multiple classes in react

Hello i'm trying to export multiple classes in react so they can be all rendered in one page. My group makes each handled a component and now where tying to bring it all together. Problem is that when we try to combine the classes we get errors that they have already been declared. Its all a learning process and while looking for solutions we saw that you can import the components and have them rendered but even looking through documentation we were a bit confused.
import styles from './ViewJobsList.css';
import { Helmet } from 'react-helmet';
import { compA, compB} from './App.js';
class compA extends React.Component {...};
class compB extends React.Component {...};
export default { compA, compB};
Now each class works on its own but together when put like this we get
Parsing error: Identifier 'compA' has already been declared
How can we export these two classes and 1 more in the future?
If you take out this line:
import { compA, compB} from './App.js';
It'll work.
The reason it's not working at the moment is because you're importing and declaring the functions in the same file. You only want to declare or import - not both.
You only want to use an import statement in files where you want the functions to be pulled across from a new file. Export is used on the file where the functions are declared.
Edit: So to import and export how you want, you need to phrase it like this:
In your app.js, you need to phrase it like:
export { compA, compB };
In your index.js, you then need to:
import { compA, compB } from "./app.js"
**Note!! If your app.js is in a different folder, i.e. a components folder, you will need to add the folder route before app.js, so it would be like:
./components/app.js**
That should be all OK - assuming you have the React and appropriate dependencies imported.
Try and delete line 3 in your snippet viz import { compA, compB} from './App.js';

Code sharing between React ES6 Classes

I'm struggling to dry up a few functions i'm using accross several of my component classes. Mixins are a no-go and I'm struggling to understand what alternative I'm supposed to use. Setting the code up as a module seems promising, but I don't understand how to package it so I can use it to extend several different class.
Say I have:
class functionsToShare {
thingToDo(){
//do a thing
}
}
export default functionsToShare;
I'm assuming in my component class I'd want something like:
import React from 'react';
import functionsToShare from 'some/path'
class SomeComponent extends React.Component{
constructor(props){
super(props);
}
render(){
return (
);
}
}
export SomeComponent
But how do I use the shared class to extend my component? If I declared it inthe class declaration likemy componenet is delcared to extend React.Component that would defeat the reusability... Is there an alternate way I should be looking at?
You can create your shared functions file as a file with several functions that you need to use, each function being exported as a named export. Like this:
export function thingToDo() {
...
}
export function getUserByEmail(email) {
...
}
Save this file as functionsToShare.js, for example.
Then in each React component class (or anywhere else) you can import that functions, just ones you need by:
import {thingToDo} from "./functionsToShare"; // import a function
thingToDo(); // call function
or all of them by:
import * as somename from "./functionsToShare"; // import all functions from that file
somename.thingToDo(); // call specific function

How to create helper file full of functions in react native?

Though there is a similar question I am failing to create a file with multiple functions. Not sure if the method is already outdated or not as RN is evolving very fast. How to create global helper function in react native?
I am new to React Native.
What I want to do is to create a js file full of many reusable functions and then import it in components and call it from there.
What I have been doing so far might look stupid but I know you will ask for it so here they are.
I tried creating a class name Chandu and export it like this
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
Text,
TextInput,
View
} from 'react-native';
export default class Chandu extends Component {
constructor(props){
super(props);
this.papoy = {
a : 'aaa'
},
this.helloBandu = function(){
console.log('Hello Bandu');
},
}
helloChandu(){
console.log('Hello Chandu');
}
}
And then I import it in any required Component.
import Chandu from './chandu';
And then call it like this
console.log(Chandu);
console.log(Chandu.helloChandu);
console.log(Chandu.helloBandu);
console.log(Chandu.papoy);
The only thing that worked was the first console.log, which means that I'm importing the correct path, but not any others.
What is the correct way to do this please?
Quick note: You are importing a class, you can't call properties on a class unless they are static properties. Read more about classes here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
There's an easy way to do this, though. If you are making helper functions, you should instead make a file that exports functions like this:
export function HelloChandu() {
}
export function HelloTester() {
}
Then import them like so:
import { HelloChandu } from './helpers'
or...
import functions from './helpers'
then
functions.HelloChandu
An alternative is to create a helper file where you have a const object with functions as properties of the object. This way you only export and import one object.
helpers.js
const helpers = {
helper1: function(){
},
helper2: function(param1){
},
helper3: function(param1, param2){
}
}
export default helpers;
Then, import like this:
import helpers from './helpers';
and use like this:
helpers.helper1();
helpers.helper2('value1');
helpers.helper3('value1', 'value2');
I am sure this can help. Create fileA anywhere in the directory and export all the functions.
export const func1=()=>{
// do stuff
}
export const func2=()=>{
// do stuff
}
export const func3=()=>{
// do stuff
}
export const func4=()=>{
// do stuff
}
export const func5=()=>{
// do stuff
}
Here, in your React component class, you can simply write one import statement.
import React from 'react';
import {func1,func2,func3} from 'path_to_fileA';
class HtmlComponents extends React.Component {
constructor(props){
super(props);
this.rippleClickFunction=this.rippleClickFunction.bind(this);
}
rippleClickFunction(){
//do stuff.
// foo==bar
func1(data);
func2(data)
}
render() {
return (
<article>
<h1>React Components</h1>
<RippleButton onClick={this.rippleClickFunction}/>
</article>
);
}
}
export default HtmlComponents;
To achieve what you want and have a better organisation through your files, you can create a index.js to export your helper files.
Let's say you have a folder called /helpers.
Inside this folder you can create your functions divided by content, actions, or anything you like.
Example:
/* Utils.js */
/* This file contains functions you can use anywhere in your application */
function formatName(label) {
// your logic
}
function formatDate(date) {
// your logic
}
// Now you have to export each function you want
export {
formatName,
formatDate,
};
Let's create another file which has functions to help you with tables:
/* Table.js */
/* Table file contains functions to help you when working with tables */
function getColumnsFromData(data) {
// your logic
}
function formatCell(data) {
// your logic
}
// Export each function
export {
getColumnsFromData,
formatCell,
};
Now the trick is to have a index.js inside the helpers folder:
/* Index.js */
/* Inside this file you will import your other helper files */
// Import each file using the * notation
// This will import automatically every function exported by these files
import * as Utils from './Utils.js';
import * as Table from './Table.js';
// Export again
export {
Utils,
Table,
};
Now you can import then separately to use each function:
import { Table, Utils } from 'helpers';
const columns = Table.getColumnsFromData(data);
Table.formatCell(cell);
const myName = Utils.formatName(someNameVariable);
Hope it can help to organise your files in a better way.
If you want to use class, you can do this.
Helper.js
function x(){}
function y(){}
export default class Helper{
static x(){ x(); }
static y(){ y(); }
}
App.js
import Helper from 'helper.js';
/****/
Helper.x
i prefer to create folder his name is Utils and inside create page index that contain what that think you helper by
const findByAttr = (component,attr) => {
const wrapper=component.find(`[data-test='${attr}']`);
return wrapper;
}
const FUNCTION_NAME = (component,attr) => {
const wrapper=component.find(`[data-test='${attr}']`);
return wrapper;
}
export {findByAttr, FUNCTION_NAME}
When you need to use this it should be imported as use "{}" because you did not use the default keyword look
import {FUNCTION_NAME,findByAttr} from'.whare file is store/utils/index'
Create a file with name e.g Utils.js and use export with all functions.
export function firstFunction(){
}
export function secondFunction(){
}
Now there are two ways you can import and use these functions
import them separately as
import {firstFunction, secondFunction} from './Utils'
and use them as
firstFunction()
secondFunction()
import them by giving generic name as
import * as Utils from './Utils'
and use them as
Utils.firstFunction()
Utils.secondFunction()

When using ES6, how can an imported function be undefined in one file, and not in another?

I'm using babel / ES6 with webpack. I'm importing the same 'actions' file - which exports a bunch functions - in two different places. At one place it returns a module, the other undefined:
actions.js
export function test() { ... }
export function test2() { ... }
App.js
import actions from './actions'
class App extends React.Component { ... }
console.log(actions); //<-------- Object{test:function,test2:function)
export default connect((state) => { ... },actions)(App);
edit
the reason App.js worked was because it was actually using import * as actions as sugested below, I just retyped it wrong in the example
NestedComponent.js
import actions from './actions'
class NestedComponent extends OtherComponent { ... }
console.log(actions); //<-------- logs undefined
export default connect((state) => { ... },actions)(NestedComponent);
Is this related to the order in which webpack defines the modules/files?
I ran into a similar issue, caused by circular dependencies. Tried to import a constant in file 'A' from file 'B' which in turn tried to import from file 'A'.
This shouldn't work in either case because you are importing the wrong values. import foo from '...' imports the default export of the module, but you don't have a default export, you only have named exports.
What you should use is
import {test, test2} from './actions';
// or
import * as actions from './actions';
Another common case where this happens is if you're testing with Jest and auto-mocking behavior is enabled. Much grief, such gotcha.

Resources