Multiple React components in a single module - reactjs

I am new to the whole browserify thing.
I have been trying to use browserify + reactify + gulp to transform, minify and combine a React application.
As long as I have a single React.createClass with a single module.exports = MyComponent everything works fine.
Since I have several shared components I physically host in the same file and reuse across projects, I would like to export more than one component.
I have tried an array:
module.exports = [Component1, Component2]
and have also tried an object with multiple properties:
module.exports = {Comp1: Componenet1, Comp2: Component2} and have also tried in-lining the calls to createClass in the object, but that didn't help.
Is there a way to do this or do I have to split every component in to a seperate JSX file?

You can do like this, with an index.js file into your /components/ folder
/components/index.js
import Users from './Users/Users';
import User from './Users/User';
module.exports = {
User,
Users
}
IMPORT
import { Users, User } from './components';
As you can see, I named my file index.js, it prevent me from write it in the import declaration. If you want to name your file with another name than index.js, you'd have to write the name of the file in the import, Node won't guess it ! ^^

I have put multiple components in one file and export the object like you suggested.
module.exports = {
comp1: Component1,
comp2: Component2
}
Then where they are used do
var comp1 = require('your/path/to/components').comp1;
var comp2 = require('your/path/to/components').comp2;

Define functions
function sum(a, b) {
return a + b
}
function sub(a, b) {
return a - b
}
function mul(a, b) {
return a * b
}
Define export
export { sum, sub, mul }
Import functions you need
import { sum, sub } from 'myfile'
or all the functions
import * as myfunctions from 'myfile'
and call as
sum(1+1) or myfunctions.sum(1+1)
src: https://flaviocopes.com/how-to-export-multiple-functions-javascript/

I'm new to react and I faced this situation too. And this is how I overcame it.
Along to this question it also answers the following error:
export 'default' (imported as 'db') was not found in './index.js' (possible exports: auth, db).
1st method - use export default & don’t destructure while importing
index.js
const db = // module 1;
const auth = // module 2;
export default { db, auth}; // notice the default keyword here
while importing in other file
import db from "./index.js"
2nd method - use export & destructure while importing
index.js
const db = // module 1;
const auth = // module 2;
export { db, auth};
and while importing
import { db } from "./index.js"
Please note when to use destructuring while using the import statement

I use function to return component.
module.exports = {
comp1: function(){
return Component1;
}
}
Then
var myCompontents = require('./components');
var comp1 = myComponents.comp1();

The following worked for me.
In a single file, MultipleComponents.js, add two or more components like below.
const ComponentA = () => <div>Component A works! </div>
const ComponentB = () => <div>Component B works! </div>
export {ComponentA, ComponentB} // Export this way without using default
Now import these components in any other component you wish like below
import {ComponentA} from 'your/directory/MutlipleFiles;

You can simply export multiple components as an array:
module.exports = [Component1, Component2]
Then to use the components:
var MyComponents = require('your/path/to/components');
var Component1 = MyComponents[0];
var Component2 = MyComponents[1];

Related

React js : how to resolve multiple export?

Hello i need to have a multiple export in react js but i have this error
Line 84:3: Parsing error: Only one default export allowed per module.
this is my code :
export default App;
export default dashboardRoutes;
What i should to do to resolve this problems please !
You can export only one default component and the other like this:
export default MostImportantComponent
// other components
export {
Component1,
Component2,
// ... etc
}
Notice that when you import the other components from other files you need to
import DefaultComponent from '...'
import { Component1, Component2 } from '...' // for other components
There are basically two types of exports.
1.Named Exports(Zero or more exports per module): This allows you to export multiple modules from a javascript file which is the case in your issue.
Solution to your case goes as follows
modules.js
export {
App,
DashboardRoutes
};
app.js
import {App,DashboardRoutes} from './modules.js'
You can equally change the names of those modules in the import file as follows
Default Exports(One per module): This allows you to export only one module, which is the reason it showed you the error you have. This gives you the advantage of using a name of your choice in the file you import it from.
modules.js page
const module1=()=>console.log('module1');
export default module1
app.js
The page that is using the modules
import MyModule from './modules.js'
You can read more about it here
you can use named export or one as default and other as named export.
Define functions
function sum(a, b) {
return a + b
}
function sub(a, b) {
return a - b
}
function mul(a, b) {
return a * b
}
Define export
export { sum, sub, mul }
Import functions you need
import { sum, sub } from 'myfile'
or all the functions
import * as myfunctions from 'myfile'
and call as
sum(1+1) or myfunctions.sum(1+1)
src: https://flaviocopes.com/how-to-export-multiple-functions-javascript/

Retrieving data from a local json file in react

How can i retrieve some data from a local json file i created in my folder? i´m using the following code:
class Intro2 extends Component {
render() {
async function getData() {
const usersData = await fetch("../articles.json");
const users = await usersData.json();
return users;
}
}
This doesn't seem to work for my local json file but if i use a url from git hub users for example its working?
many thanks
The error: main.chunk.js:332 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
You shouldn't be using fetch.
Use import instead. This will ensure webpack doesn't bundle the json file.
But makes it available in the public directory.
const usersData = await import("../articles.json");
Fetch will never work because webpack won't serve your JSON file.
Not unless you put it in a the static or public folder.
I think if you're trying to read from your file system you won't be able to do it, because in at least some browsers, you will need to serve the file via a web server process.
But if you are trying to read from http://localhost:9000/articles.json the issue could be another thing.
Maybe you need the {mode:'no-cors'} param ?
fetch('../static/test.txt', {mode: 'no-cors'})
Else you could simply export it:
export const json = () => ({...})
and then import it to your file:
import {json} from '../json
Assuming the json is in the project's folder structure.
import React from "react";
import ReactDom from "react-dom";
import usersData from "../articles.json";
class Intro2 extends React.Component {
state = {
usersData: { ...usersData },
};
componentDidMount() {
// a place for promises
};
render() {
// where the jsx is rendered
return <div>Renders JSX with state {this.state.usersData.aKey}</div>;
}
};
or with react functional components
// Alternatively, use functional components:
import React from "react";
import usersData from "../articles.json";
function Intro2() {
const [usersData, setUsersData] = React.useState({ ...usersData });
return <div>Renders JSX with state {usersData.aKey}</div>;
}

import file dynamically by variable - react native

I have a path.json file that contains the path of a component
// path.json
{
"main": "./login/index.js",
"paths": [
{
"name": "login",
"path": "./login/index.js",
"image": ""
}
]
}
I want to load './login/index.js' file dynamically in react native and render this particular file
My current implementation
const MyComponent = createLazyContainer(() => {
const componentPath = PathJson.main; // ./login/index.js
return import(`${componentPath}`); //import error here # line 7
});
export default MyComponent;
I am getting following error :
Invalid call at line 7: import("" + componentPath)
What people have been telling you in the thread is correct but I'd like to add one possible solution. All the imports/require are resolved at compilation time and not at running time which you are trying to do. By the time you are running your app, if you haven't imported the files, you can't use them.
There is a workaround tho, assuming that you know all the files that you might in advance which is to do something like a factory:
const possiblePaths = {
'one': require('path/to/file/1'),
'two': require('path/to/file/2')
}
function(type){
return possiblePaths[type];
}
And then you use it somehow like:
render(){
const MyComponent = function('one');
return <MyComponent/>;
}
This is more or less pseudo code and my not work right away, but hopefully yo get the idea. You need to store a reference to each of the imports you might need and then dont use the import, use the reference that was created for you at compilation time.
Actually, the React Native development concerns are not like development for the Web.
Just for this reason, it is not so important at all to have lazy loading in the production of a react-native project. Just import anything you want and then use them in any files of the project. all of them are in the bundle of production and exactly it is not important at all.
So for this problem, I prefer to have a helper file to collect all selectable libraries and export them:
// helper file
export { default as Index } from './Login';
export { default as OtherComponent } from './OtherComponent';
Then when you wanna use:
import { Index, OtherComponent } from 'helper';
~~~
render() {
const MyComponent = someCondition ? Index : OtherComponent;
return (
<MyComponent />;
);
}
Solution:
const allPaths = {
path1: require('file path1').default,
path2: require('file path2').default
};
render(){
const MyComponent = allPaths["path1"];
return <MyComponent/>
}
In React Native all the files that are being imported are bundled together, only those files can be dynamically imported.
Let's say you have three files index.js, test_1.js and test_2.js and if you have imported only test_1.js in index.js than React Native will only bundle those two files leaving test_2.js.
So to answer your question even if dynamic import works in React Native but because these files are not part of the bundle you are not able to import them.
I've once been in a similar situation where I need to do imports by variable, but that is limited to importing components inside a component and it uses code-splitting (Edit: I'm playing around to look for a solution without relying on code-splitting, I just realized there was a react-native tag in the question, and I don't think code-splitting is a good choice to go with in RN). I'm not sure by how much my method could help you, but here goes.
Side notes:
Importing folder that contains an index.js(jsx|ts|tsx) file should automatically resolve to that index file.
Importing from from './login/index.js' usually throws a 'Module not found' error. Either import from './login/index' or from './login but I prefer the last one as it's the shortest & simplest.
In path.json:
{
"main": "./login", // '.js' is removed
"paths": [
{
"name": "login",
"path": "./login/index.js", // Not sure what this is for, but if necessary, remove the '.js' here as well
"image": ""
}
]
}
In MyComponent.js:
import React, { lazy, Suspense } from 'react'
import PathJson from './path'
// 1. We need a UI to show while component is being loaded
const Loader = () => <div>{'Loading...'}</div>
// 2. We need a fallback UI if component is not found
const DocUnavailable = () => <div>{'We\'re sorry, but this document is unavailable.'}</div>
// 3. Create a resolver function ('resolver' is just a name I give)
function resolveImport(pathToComponent, FallbackComponent) {
let componentFound = false
let RenderComponent = () => <FallbackComponent /> // Assign fallback first
try {
if (require.resolve(pathToComponent)) {
componentFound = true
}
} catch (e) { } // Kinda hacky, if you don't mind, but it works
if (componentFound) {
// If found, replace fallback with the valid component
RenderComponent = lazy(() => import(pathToComponent))
}
return RenderComponent
}
// 4. Finally, implement it in a component
class MyComponent extends React.Component {
render() {
const componentPath = PathJson.main
const RenderComponent = resolveImport(componentPath, DocUnavailable)
return (
<Suspense fallback={<Loader />}>
<RenderComponent />
</Suspense>
)
}
}
export default MyComponent
References:
Implementation for 'resolver' function based on Langutil
Code-splitting with lazy & Suspense based on React Docs

How to import correctly js library (gigraph), into react

I'm trying to import gitgrapqh into React, following their demo, but I got an error, apparently load for a fraction of second la later raise an error.
App.js file
import React, { Component } from 'react';
import 'gitgraph.js';
import 'gitgraph.js/build/gitgraph.css';
export default class Gitgraph extends Component {
constructor(props) {
super(props);
this.$gitgraph = React.createRef();
}
componentDidMount() {
const gitgraph = new GitGraph({ canvas: this.$gitgraph.current });
const master = gitgraph
.branch("master")
.commit()
.commit();
gitgraph
.branch("dev")
.commit()
.commit()
.merge(master);
}
render() {
return <canvas ref={this.$gitgraph} />;
}
}
But I got this error.
Failed to compile
./src/App.js
Line 13: 'GitGraph' is not defined no-undef
Search for the keywords to learn more about each error.
Someone can help me.
In React projects (and actually in all modern JavaScript projects), you split your code across multiple JavaScript
files - so-called modules. You do this, to keep each file/ module focused and manageable.
To still access functionality in another file, you need export (to make it available) and import (to get access) statements.
You got two different types of
exports: default (unnamed) and named exports:
default => export default ...;
named => export const someData = ...;
example#01:
#Person.js
const person = { name: "firstName" }'
export default person;
Now you should use import Person from 'Person'
example#02:
#clean.js
export const clean = () => ...}
then you should use import { clean } from 'clean'
default export:
import person from './person';
import prs from './person';
named export:
import { smth } from './utility';
import { smth as Smth } from './utility';
import * as bundled from './utility';

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()

Resources