Pass data from one component to another using ReactJS - javascript

I have the following in App.js
let contracts = [
{
id: "1",
name: "Lloyds",
image: ""
}
];
class App extends Component {
render() {
return (
<div>
<Header />
<Search />
<ContractsList />
<Content />
<Footer />
</div>
);
}
}
export default App;
Im trying to pass the contracts variable as a prop in my index.js file
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap-grid.css";
ReactDOM.render(
<React.StrictMode>
<App contracts={contracts} />
</React.StrictMode>,
document.getElementById("root")
);
but keep getting the following error:
Line 10:21: 'contracts' is not defined no-undef
how can i use the contracts variable so it can be used as a prop in other components?

You need to shift your contracts array from app.js to index.js and then pass it as a props.
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap-grid.css";
let contracts = [
{
id: "1",
name: "Lloyds",
image: ""
}
];
ReactDOM.render(
<React.StrictMode>
<App contracts={contracts} />
</React.StrictMode>,
document.getElementById("root")
);

contracts is not defined in your index.js file. Either you define contracts there, or you import it.
And then, you need to pass it to the underlying components in App.js too, for example:
<Content contracts={this.props.contracts} />
(For every component in which you need it.) Why are you trying to pass it in index.js at all?

The error is coming on the index.js file on this line:
<App contracts={contracts} />
here you dont have any variable called contracts, you may need to put a variable contracts in this file instead of App.js.
Hope this helps!

You've defined contracts in a different file to the one you're trying to use it in. Define contracts in index.js and it'll work.

you need to export the contracts
Demo
App.js
export const contracts = [
{
id: "1",
name: "Lloyds",
image: ""
}
];
index.js
import App,{contracts} from "./App";
For better. its already in app.js . so you can access with in app.js .no need to pass from index.js

Related

Importing App into react js results on module error

Im making a simple typescript project, but can't manage to solve the following error:
Compiled with problems:
ERROR in ./src/index.tsx 7:0-28
Module not found: Error: Can't resolve './App' in '/Projects/test/src'
Any suggestions??
Here's the files..
Home:
import React from "react"
export const Home = () => {
return (
<>
<div>
<p>Essa é a pagina home</p>
</div>
</>
);
};
export default Home;
App.tsx:
import React from 'react';
import { Home } from './pages/Home';
export function App() {
return (
<Home />
);
};
index.tsx:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { App } from './App';
const ApplicationWrapper = () => {
return (
<App />
);
};
ReactDOM.render(
<React.StrictMode>
<ApplicationWrapper />
</React.StrictMode>,
document.getElementById('main'),
);
FILE STRUCTURE:
When the code is exported and with a default keyword, that means you only can import by using import Alias from './module'. If you want to import through Object Destructuring, it needs to export a Component or module without using the default keyword.
Last line of Home component.
export { Home };
When it needs to import.
import { Home } from './path-to-component';
you can export once at Home component like this:
import React from "react"
const Home = () => {
return (
<>
<div>
<p>Essa é a pagina home</p>
</div>
</>
);
};
export default Home;
Please check, App.tsx file should be in index.tsx folder. ie both files should be in /Projects/test/src folder.

cannot render a <Router> inside another <Router>. You should never have more than one in your app

This is my index.js code
import React from "react";
import { render } from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { BrowserRouter } from "react-router-dom";
import "#fortawesome/fontawesome-free/css/all.min.css";
import "bootstrap-css-only/css/bootstrap.min.css";
import "mdbreact/dist/css/mdb.css";
import { createStore } from "redux";
import { userReducer } from "../src/reducers/UserReducer";
import { Provider } from "react-redux";
import { loadState, saveState } from "./store/LocalStorage";
const persistedState = loadState();
let store = createStore(userReducer, persistedState);
store.subscribe(() => saveState(store.getState()));
render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
serviceWorker.unregister();
This is the error I am getting on browser
"Error: You cannot render a <Router> inside another <Router>. You should never have more than one in your app."
Please help me with some solution.
I guess you are using React Router 6. They dropped support for nested Routers(like MemoryRouter inside of BrowserRouter or any other combinations)
https://github.com/remix-run/react-router/issues/7375
There is rather a hack with <UNSAFE_LocationContext.Provider but as name suggests it's not guaranteed this will work for any(even patch version) updates.
I suggest you either going back to V5 or getting rid of nesting.

Magic? Where does the React Context Provider come from? Naming convention?

I am using firebase auth in my app and it's working - however I'm struggling to understand how the provider passes data into the App component in App.js.
It doesn't appear to be passed in explicitly. Is there a naming convention or something that's passing the data?
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
App.js
import React from 'react';
import firebase from './firebase'
import withFirebaseAuth from 'react-with-firebase-auth'
import SignInPage from './SignInPage'
import AppContainer from './AppContainer'
const firebaseAppAuth = firebase.auth();
function App(provider){
return (
<div className="App">
{
provider.user // if user from the provider
? <AppContainer
authUser={provider.user}
signOut={provider.signOut}
/>
: <SignInPage
signInWithGoogle={provider.signInWithGoogle}
error={provider.error}
/>
}
</div>
);
}
const providers = {
googleProvider: new firebase.auth.GoogleAuthProvider()
};
export default withFirebaseAuth({
providers,
firebaseAppAuth,
})(App);
You're getting the provider from the HOC withFirebaseAuth. It wraps your component. That's why you can use the provider even though you didn't pass it, the HOC 'provided' it.

React jest - You should not use <Link> outside a <Router>

I have a super simple react app like so.
index.tsx
App.tsx
Main.tsx
Home.tsx
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter as Router } from "react-router-dom";
import { ApolloProvider } from "react-apollo";
import client from "./utils/client";
ReactDOM.render(
<Router>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</Router>,
document.getElementById('root')
);
App.tsx
import React from 'react';
import Main from "./Main";
function App() {
return (
<Main />
);
}
export default App;
Main.tsx
import React from 'react';
import { Switch, Route, Link } from "react-router-dom";
import Home from "./Home";
const Main:React.FC = () => {
return (
<div>
<Switch>
<Route exact path='/' component={Home} />
</Switch>
</div>
);
};
export default Main;
Home.tsx
import React, {useContext} from 'react';
import { Link } from "react-router-dom";
const Home:React.FC = () => {
return (
<div>
<h1>Home</h1>
<Link to='http://google.com'> Google</Link>
</div>
);
};
export default Home;
I have an App.test.tsx with a dummy test just to run it.
import React from 'react';
import { render, screen } from '#testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
expect(true).toBeTruthy
});
If I run the test with yarn test
I get an error:
Invariant failed: You should not use <Link> outside a <Router>
The Link I have is in Home.tsc which is surrounded by <Router> in index.tsx
I'm I doing something work here.
The app runs without any errors.
This error only appears when I run the test
There are two solutions below, the first is to add <Router> component into your test case. The second option is to switch from <Link> to a simple anchor tag.
Option 1:
You can add <Router> component into your test also, so it won't missing there as:
test('renders learn react link', () => {
render(<Router>
<App />
</Router>);
expect(true).toBeTruthy
});
Option 2:
Also you can change from <Link> component to a simple anchor tag because it creates the same end result based on your code from:
<Link to='http://google.com'> Google</Link>
To the following in <Home> component:
Google
Then at the end you can keep your original test case.

Problem with exporting/importing React component

I'm trying to create a React component for a navigation bar.
This component I'd like to import from a separate file into my App.js.
Currently, the component should just return a simple 'Hello world' paragraph, but I have trouble getting this to work.
I have written the following code into a file located at src/components/navbar.js:
import React from 'react';
export default class navBar extends React.Component {
render() {
return (
<p>Hello world.</p>
)
}
}
Now I'd like to import this component from my src/App.js, which looks like this:
import React, { Component } from 'react';
import './App.css';
import navBar from './components/navbar.js'
class App extends Component {
render() {
return (
<navBar/>
);
}
}
export default App;
If I compile and open the site, nothing's there, which confuses me.
I'd be very thankful for any help!
EDIT:
It's been suggested that the problem is that <App /> is not being rendered anywhere. I don't believe that's the case, since there's another file being created by default (index.js), which looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
I have also tried putting the paragraph (and the entire navbar) directly into src/App.js.
After compiling I could see the expected results in the browser, so the problem should lie with the exporting/importing.
In JSX, lower case tags are considered to be simple HTML/SVG elements. You can use lower case only if you use accessors (so with a dot like bla.blabla).
You can read about it here for example.
So in your case you must change the class name navBar to NavBar and then in the render method:
render() {
return (
<NavBar/>
);
}
Here is a full working example:
** Note: NavBar.js shoud start with a Capital letter.
App.js
import React from "react";
import ReactDOM from "react-dom";
import NavBar from "./components/NavBar";
function App() {
return (
<div className="App">
<NavBar />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
NavBar.js
import React from "react";
export default class NavBar extends React.Component {
render() {
return (
<div>
<p>Hello world.</p>
</div>
);
}
}

Categories