I starting using React. I have a main file (App.js) where all logic comes and in that file, I have added routes (, , ) which loading different page by URL from other files (only content).
In App.js constructor I added the web3 package and write that in a variable (window, global variable) because that is only one way to get that variable in other components files. I don't want to use window variables, because every user can see that. I want to use const/var variables, but get that values in every single component files, but I don't want to load same web3 library (or to connect smart contracts in every single component file). How to do that?
Assuming you mean everything web3 has. On your component file
import React from 'react';
import Web3 from 'web3';
const ComponentA () => {
// Do what ever you want with Web3 and react code here
};
export default ComponentA;
If you want the instance of web3 you created, maybe you could initialize web3 in its own file.
your own web3_instance.js
import Web3 from 'web3';
const web3Instance = new Web3();
export default web3Instance;
Then import it to any component.
import React from 'react';
import web3Instance from '../path/to/web3instance.js';
const ComponentA () => {
// Do what ever you want with web3Instance and react code here
};
export default ComponentA;
Related
I'm ultimately trying to dynamically create an object of imported components to export all at once. But in my simple example below, I can't even export an object with 1 component. Why is that?
// index.js
// Card is a standard ReactJS component, exported with export default Card
import Card from './Card';
let Components = {};
Components['Card'] = Card;
// this also doesn't work
// Components['Card'] = require('./Card').default
export default Components;
// Error message: "Attempted import error: 'Card' is not exported from './index.js'"
As the error says, you don't have a named export Cards. You have a default export, Components, which is an object with a property Cards.
If you want to have named export Cards then do
export {Cards};
Or if you don't even need the Components object, you can re-export the component directly with
export {default as Card} from './Card';
However if you really do want to export a default object that holds one or more components as properties, then import it accordingly:
import Components from './index.js';
// use Components.Cards were necessary
See the export documentation on MDN for more information.
Two solution here. Firstly when you assign a component into the Components object you can assign Card as a component like below.
Components['Card'] = <Card/>
and then use it like this
<div>{Components.Card}</div>
Secondly and My favorite is, whatever you have done in the index.js file to store the component is ok. But when you are using it use it like below.
<Component.Card/>
Example
As title. I've searched about this problem on this site but I didn't find a solution for my case.
I've defined a global variables in public/static/js/A.js in my Visual Studio project:
var pVariable=new Class1();
There is a function LoadList() in Class1.
That variable will be used in several functions in my project, so I set as a global variable, and I included the JS file to public/index.html in the same project:
<script type="text/javascript" src="%PUBLIC_URL%/static/js/A.js"></script>
I use that variable in src/Clsb.js in the same project....
var alist=pVariable.LoadList();
export default class Clsb extends Component{
render(){
return (<Table dataSource={alist} />);
}
}
When I start debug in Visual Studio , I got an error:Failed to compile: 'pVariable' is not defined no-undef
But I am sure the JS file contains that variable is included. Could someone guide me to fix where I made it wrong?
You can do that by storing the variable in window variable
first store the value of your variable in A.js like this
window.pie = 3.1416;
And you can see the variable value in your Clsb.js component like
console.log(window.pie);
As phuzi said in the comment to your question, declaring global variables in react is a bad idea, in this case the ideal would be to use redux, or else the context api (context hook) so you can access and make the variable available throughout your system.
Link to docs
https://reactjs.org/docs/context.html
👇 context with functional component
let's create a context like hook
/src/context.js
import React, { createContext, useState, useContext} from "react";
const UserContext = createContext();
export default function UserProvider({ children }) {
//your variables
//example
const [person, setPerson] = useState('John');
return (
<UserContext.Provider
value={{
person //variables to export
}}
>
{children}
</UserContext.Provider>
);
}
export function useUser() {
const context = useContext(UserContext);
if (!context) throw new Error("useUser must be used within a CountProvider");
const { person } = context;
return { person };
}
after creating the context, around your app you need to place the provider
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import UserProvider from "./src/context.js";
ReactDOM.render(
<UserProvider>
<React.StrictMode>
<App />
</React.StrictMode>
</UserProvider>,
document.getElementById("root")
);
after you already have the provider you can access any file
src/page.js
import React from "react";
import { useUser } from "./context.js";
const Page = (props) => {
const { getPerson } = useUser(); //variable available by context
return (<h1>Test h1</h1>)
};
export default Page ;
obs: i didn't test the code
Global variables is not a good practice in React. Whenever you find you find yourself needing that, it's most likely that what you want us instead Global state Management.
My recommendation is :
-first to try React's built in global state Management toolsn like Context API https://reactjs.org/docs/context.html
-Then if the first doesn't serve your need, try third party state Management libraries like redux from https://react-redux.js.org/introduction/ or mobx
I have a files like this:
components/carousel.js
import hammerjs from 'hammerjs';
import React from 'react';
export default () => <div>...</div>;
components/layout.js
import React from 'react';
export default () => <div>...</div>;
components/index.js
export { default as Carousel } from './carousel';
export { default as Layout } from './layout';
Now in my server side rendered app I import layout like so:
import { Layout } from './components';
I get an error about window not being defined, because it's reading through components/index.js and seeing hammerjs dependency inside the Carousel export, which requires window and isn't available on the server.
Why is it reading the code in the Carousel component when I'm only trying to import the Layout component? How do I avoid this happening?
In short - why is it reading the Carousel component?
You are exporting two defaults in your components/index.js which is not a supported operation. Export the named components individually or one default objet that holds both.
1) From MDN on import/exports - You can have multiple named exports per module but only one default export. link
In your components index file you're exporting both as default - export the named variable. Then import the named variable.
2) The HammerJS dependency shouldn't matter. Your react code will be run through some sort of transpiler that will take the node modules and turn them into something the browser can understand.
For context, let me try to explain a little more.
In my project I have a folder, as example, for components.
Inside that folder I have my components files, and an index.js file where I import all the components and export than in the same line as follows:
export { default as Button } from './button'
export { default as Loader } from './loader'
export { default as ImageBackground } from './image-background'
So than I can import these components in Screen Component like that:
import { Button, Loader, ImageBackground } from 'src/components'
If I edit the components file, save and reload the project, everything works fine.
The problem is that when I edit any of these components with the Hot Module Replacement (Hot Reloading) actived, when it is triggered after an edit, it throws the following error:
Unhandled JS Exception: Requiring module "src/components/index.js", which threw an exception: TypeError: Cannot redefine property: Button
Has anyone have any idea why this is happening?
Thanks in advance!
Obs: When I import the component direct without using the index.js or if inside the index.js, I first import the component, than I assign the component to a variable and than I export this variable, it works fine.
my problem was solved when I changed render = () => (...) to render(){ return (...)} in react component
I am using Styled Components but getting a problem trying to style a component of my own creation.
It is exported in the normal way from a separate npm package.
Package
FormComponents.js
export SubmitButton from './_submit-button';
_submit-button.js
export styled.button`somestyles`;
components.js
import * as Form from './form-components';
export { Form }
index.js
import * as Components from './components'
export const FormComponents = Components.Form;
Then in my actual component I want to use it I have:
import { FormComponents as Form } from 'packagename';
const Button = styled(Form.SubmitButton)...
and I'm receiving the error cannot read SubmitButton of undefined.
If however I put the const Button = ... in the render method, it finds everything fine. So I assume that the component isn't being instantiated until React kicks in.
It's possible with other elements however, for example if I change it to use:
const Button = styled(Link)
(Link from react-router-dom)
it finds it fine.
Am I exporting wrong?