Classes based on React.Component - javascript

New, new, new to React. Downloaded the following sample of setState method in classes that extend React.Component. It works fine, but I'm not understanding why no object needs to be instantiated for App, since each user could be in a different location...
I somehow thought index.js would need:
const app = new App()
Is there a reason for this?
index.js
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor ( props ) {
super ( props );
this.state={ latitude: null};
window.navigator.geolocation.getCurrentPosition (
( postion ) => {
this.setState( {latitude: postion.coords.latitude })
},
( error ) => console.log ( error )
);
}
render () {
return (
<div className="App">
<header className="App-header">
<p>
LATITUDE: {this.state.latitude}
</p>
</header>
</div>
);
}
}
export default App;

Actually you do instanciate objects everytime you use a React component. You can translate const app = new App() by using <App/> in your code. In your case, one instance is in the ReactDOM.render function.

Related

React - Render more than one Component

I have the typical index.js that calls App.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
App.js
import './App.css';
import Test from './Components/test'
import Test1 from './Components/test1'
function App() {
return (
<Test/>,
<Test1/>
);
}
export default App;
When building App.js i wanted to render 2 components Test and Test1
When i run this code only one of the components gets rendered. In this case only Test1 is rendered. If i switch the order only Test is rendered
Is there any way that i can render 2 components?
You can only render one component, so an approach would be to wrap them in one. For example, in a React Fragment, like so:
import { Fragment } from 'react'
...
return (
<Fragment>
<Test />
<Test1 />
</Fragment>
)
Fragment is just a wrapper, it doesn't provide any functionality. Alternatively, you can wrap your components like so:
return (
<>
<Test />
<Test1 />
</>
)
The result would be the same.
You need to wrap this Test and Test1 into some wrap
import './App.css';
import Test from './Components/test'
import Test1 from './Components/test1'
function App() {
return (
<div>
<Test/>,
<Test1/>
</div>
);
}
export default App;
try this
function App() {
return (
<>
<Test />
<Test1 />
</>
)
}

Props appear like undefined when a children is passing too

I try to pass a children and props to my component, the children pass well, but the props come like undefined, I cannot figure why. When I don't use children that's work fine. A little snippet to understand the problem.
the function
import React from "react";
export function PropsChildren({ children }, props) {
console.log("info props", props.name, props.age);
return (
<div>
<p>Props name is {props.name}</p>
<p>Props age is {props.age}</p>
</div>
);
}
the call
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
//import App from './App';
import reportWebVitals from "./reportWebVitals";
import { PropsChildren } from "./props/props_children";
ReactDOM.render(
<React.StrictMode>
<PropsChildren name="Knupel" age={46}>
{document}
</PropsChildren>
</React.StrictMode>,
document.getElementById("root")
);
console return
info props undefined undefined
props is not the second argument. The props and present the the first object and children is also present there.
export function PropsChildren({ children, ...props }) {
console.log("info props", props.name, props.age);
return (
<div>
<p>Props name is {props.name}</p>
<p>Props age is {props.age}</p>
</div>
);
}

React - print content of imported component function

Trying to split some HTML chunks by dividing the HTML in smaller pieces, located in the components folder. (I know, HTML is not really html, it is JSX).
The outcome I am trying to achieve is to have the imported component [Navigation] to render its content.
I do understand that there might be tools for the code splitting.
Question: Why doesnt the code render the div navigation content?
Navigation.js
import React from 'react';
export default function Navigation() {
return (
<div className="navigation">
<ul>
<li>
Google
</li>
</ul>
</div>
);
}
App.js
import React from 'react';
import './App.css';
import Navigation from './components/Navigation';
class App extends React.Component {
render() {
Navigation();
return (
<div>
Hello from component - Class!
</div>
);
}
}
export default App;
Index.js
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();
Your component is not rendering because u call de function outside the return statement.
For a component render, you need to return the component inside the
render function;
Example:
render () {
return <Component/>
}
When u call this:
render() {
Navigation(); // see, the navigation is outside the return statemente
return (
<div>
<p>Hello from component - Class!</P>
</div>
)
}
try this:
import React from 'react';
import './App.css';
import Navigation from './components/Navigation';
class App extends React.Component {
render() {
return (
<div>
<Navigation/>
<p>Hello from component - Class!</P>
</div>
)
}
}
export default App;

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>
);
}
}

How to call `connect` from the same component which has `Provider` context to import redux state?

I used to have Provider context wrapped around my top React component: App. I then decided to move the context directly to ReactDOM.render so that I can use redux connect in App. I want to use connect so that I can use a loader (LinearProgress) as the top component in my app. So I will import loading from props and display a loader accordingly (loading could be toggled from some inner component).
However I keep getting this error:
Warning: Cannot update during an existing state transition (such as withinrender). Render methods should be a pure function of props and state.
The page is still rendered normally but I have the above error in the console. I checked the line which causes the error is the following one (inside App):
{loading && <LinearProgress color='secondary'/>}
If I remove the line then no errors are reported in the console. Why conditional display of loader inside App causes the error?
This is the code of the App component:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import LinearProgress from '#material-ui/core/LinearProgress';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import SearchAppBar from './components/layout/MaterialHeader.js';
import AppInfo from './components/appOperations/AppInfo.js';
import About from './components/layout/About.js';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import constants from './constants';
class App extends Component {
render() {
const { loading } = this.props;
return (
<Router>
<div className="App">
{loading && <LinearProgress color='secondary'/>}
<SearchAppBar/>
<Switch>
<Route exact path="/" />
<Route exact path={constants.CLIENT_ROUTES.APP} component={AppInfo}/>
<Route exact path="/about" component={About}/>
</Switch>
</div>
</Router>
);
}
}
App.propTypes = {
loading: PropTypes.bool.isRequired
};
const mapStateToProps = state => ({
loading: state.app.loading
});
export default connect(mapStateToProps, null)(App);
This is the code of the parent and top-most component of App:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import './index.css';
import MuiThemeProvider from '#material-ui/core/styles/MuiThemeProvider';
import App from './App';
import MaterialBlueTheme from './components/layout/MaterialBlueTheme.js';
import * as serviceWorker from './serviceWorker';
import store from './store.js';
ReactDOM.render(
<Provider store={store}>
<MuiThemeProvider theme={MaterialBlueTheme}>
<App />
</MuiThemeProvider>
</Provider>
, document.getElementById('root')
);
serviceWorker.unregister();
Look for a one of your components that is trying to change the state within the render method. You can't do this:
render() {
this.setState({
...
});
return (...);
}

Categories