Unable to make a component unmount - javascript

I have a little big personal project, and I figured out (after 3 months of code) that none of my components ever unmount.
I created a new-react-app to test in a brand new environment, and it didn't work either.
Here's my class :
import React, { Component } from 'react';
import logo from './logo.svg';
import Test from './Test'
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
test: true
}
this.test = this.test.bind(this)
}
test(){
this.setState({
test: !this.state.test
})
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
{this.state.test ? <Test /> :null}
<button onClick={this.test}/>
</div>
)
}
}
export default App;
here's console's result
console
Thank you for your time !
EDIT : I discovered that in every class I always called componentSWillUnmount instead of componentWillUnmount... thanks everybody

When you toggle the test state, your Test component does unmount. You maybe looking at some incorrect information. See the snippet below
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
test: true
}
this.test = this.test.bind(this)
}
test(){
this.setState({
test: !this.state.test
})
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
{this.state.test ? <Test /> :null}
<button onClick={this.test}/>
</div>
)
}
}
class Test extends React.Component {
componentDidMount() {
console.log('mounted');
}
componentWillUnmount () {
console.log('unmounting');
}
render() {
return (
<div className="test">
Hello
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>

Related

React calling function?

Slightly new to react and playing around with lists, not sure why my code isn't performing as required, when I call the method it just displays plain html
Ive tried putting it between tags but nothing
Can someone point out what I'm doing wrong?
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import List from './List'
class App extends Component { //different
render() { //different
// The rest of the file is the same
return(
<div className="App">
Liste();
</div>)
};
}
function Liste(){
const names=['d','d']
return(<div>
<h2>{names[0]}</h2>
<h2> {names[1]}</h2>
</div>)
}
export default App;
Your Liste function is a functional component so it needs to be included like any other react component and not to be executed as a function. Just replace your return statement in your App component to
return(
<div className="App">
<Liste />;
</div>)
};
You can go through this link to learn the syntax - https://devhints.io/react
Try this out
const Liste = () => {
const names=['d','d']
return(
<div>
<h2>{names[0]}</h2>
<h2> {names[1]}</h2>
</div>
);
};
class App extends Component {
render() {
return(
<div className="App">
<Liste />
</div>
);
};
}
export default App;
Try this.
class App extends Component { //different
render() { //different
// The rest of the file is the same
return(
<div className="App">
{Liste()}
</div>)
};
}
function Liste(){
const names=['d','d']
return(<div>
<h2>{names[0]}</h2>
<h2> {names[1]}</h2>
</div>)
}
export default App;

two component can display in reactjs

I have two component in the same work space in reactjs but just one is displaying
import React, { Component } from 'react';
import logo, { ReactComponent } from './logo.svg';
import './App.css';
import ReactDOM from "react-dom";
class App extends React.Component {
render() {
let helloWorld = 'Welcome to good programming React';
return (
<div className="App">
<h2> {helloWorld}</h2>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ value: event.target.value })
}
handleSubmit(event) {
alert(this.state.username)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.username} onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
)
}
}
export default (App,Form)
output from browser gives just the form.how can i do to display both App and form
The problem here is that you are mounting the node <App/> but it does not contain your <Form/> component.
You just need to call <Form/> inside your <App/> component like this
class App extends React.Component {
render() {
let helloWorld = 'Welcome to good programming React';
return (
<div className="App">
<h2> {helloWorld}</h2>
<Form/>
</div>
);
}
}
Call <Form /> inside App component and then export your App component
export default App;
You might not be understanding how React works, and you might be confused with this code
ReactDOM.render(<App />, document.getElementById('root'));
What this code essentially does is renders the App Component into the element in the index.html with the id root. The reason why your second component is not rendering is because it is not experiencing a ReactDOM.render nor is it included in the App Component.
By convention, App component should be the only component experiencing ReactDOM.render, and all the other component to be rendered must be inside the App component. Just like what #sudo97 is saying
ReactDOM.render function needs to have the Root component or the parent component which is to be passed as a first parameter.
ReactDOM.render(<App />, document.getElementById('root'));
Here App is the root component, you can include <Form /> inside of the App component to render both the components.
You are not rendering the <Form /> component. Heres the simplest solution code to solve your issue:
import React from "react";
import ReactDOM from "react-dom";
import "./App.css";
class Form extends React.Component {
constructor(props) {
super(props);
this.state = { username: "" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
alert(this.state.username);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.username}
onChange={this.handleChange}
/>
<input type="submit" value="Submit" />
</form>
);
}
}
class App extends React.Component {
render() {
let helloWorld = "Welcome to good programming React";
return (
<div className="App">
<h2> {helloWorld}</h2>
<Form />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
export default App;

Variables in React

I've been working with React for the last days, so don't blame me.
But I'm trying to display my full name with a button but I get an error when I d this.
import React from 'react';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Val',
surname: 'Vree',
age: 17,
nationality: 'Netherlands'
};
}
render() {
return (
<div>
<Header header={this.state.name} />
<Content content={this.state.surname} />
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<p>I'm {this.props.content}</p>
</div>
);
}
}
export default App;
How can I put multiple variables in the Content class? Sorry for everything, because I been learning it for some days and I don't have some knowledge of React.
you can pass it in a few ways:
<Content content={ `${this.state.name} ${this.state.surname}`} />
or
<Content name={this.state.name} content={this.state.surname} />
and get
class Content extends React.Component {
render() {
return (
<div>
<p>I'm {this.props.name} {this.props.content}</p>
</div>
);
}
}
just add multiple props. if your feeling lazy want just one prop just pass this.state and you can pass the entire object. but this is bad practice generally.
hope this helps
import React from 'react';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Val',
surname: 'Vree',
age: 17,
nationality: 'Netherlands'
};
}
render() {
return (
<div>
{/* <Header header={this.state.name} /> */}
<Content
name={this.state.name} //<---- add more props
surname={this.state.surname}
age={this.state.age}
nationality={this.state.nationality}
/>
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<p>I'm {this.props.name} {this.props.surname}</p>
<p> I am {this.props.age} and i'm from {this.props.nationality}</p>
</div>
);
}
}
export default App;
When you say variables I think you mean props. You can pass props from a parent component to a child component like so
<ChildComponent propOne={this.state.stateOne} propTwo={this.state.stateTwo} />
Now ChildComponent has access to both of those props passed down from the parent component.
In ChildComponent you can access propOne by doing props.propOne (or this.props.propOne if ChildComponent is a class component).
In your case, you should do
import React from 'react';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Val',
surname: 'Vree',
age: 17,
nationality: 'Netherlands'
};
}
render() {
return (
<div>
<Header header={this.state.name} />
<Content name={this.state.name} surname={this.state.surname} />
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<p>I'm {this.props.name} {this.props.surname}</p>
</div>
);
}
}
export default App;

ReactJS memory leak at reloading Img source

I have written a multipage app using ReactJS. When a page/component with an is re-rendered, the browser memory increases. It seems the memory is not cleared when the component is unmounted. I expect the browser memory to decrease when the component is unmounted. Does anyone have a suggestion how to clear the memory for this image at unmount?
thanks,
Tim
import React from 'react';
export class About extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<div id='about' >
<div className="container">
<div className="row">
<div className="col-md-6">
<h2>title</h2>
<p>getting your ideas made</p>
</div>
<div className="col-md-6">
<img src="app/images/pic3.png" alt=""/>
</div>
</div>
</div>
</div>
)
}
}
update:
Below is the Parent component that the page is mounted to:
import React from 'react';
import ReactDOM from 'react-dom';
import {RightPane} from './components/RightPane.js'
import {LeftPane} from './components/LeftPane.js'
import {ModelLibrary} from './components/ModelLibrary.js'
import {ProjectsListing} from './components/ProjectsListing.js'
import {About} from './components/page_about.js'
import {Renderer} from './components/Renderer.js'
function MainSwitch(view){
switch (view) {
case 'listing':
return <ProjectsListing />
break;
case 'viewer':
return (
<div>
<Renderer />
<LeftPane />
<RightPane />
</div>
)
break;
case 'about':
return <About />
break;
default:
return (
<div>
<Renderer />
</div>
)
}
}
export class ReactRoot extends React.Component {
constructor(props) {
super(props);
this.state={
mainpage:''
}
}
showPage = (event)=>{
console.log(event.detail);
this.setState({
mainpage:event.detail
})
}
componentDidMount(){
window.addEventListener('page-change', this.showPage, false);
}
componentWillUnMount(){
window.removeEventListener('page-change', this.showPage, false);
}
render() {
return (
<div >
<div id='mainpage'>
{MainSwitch(this.state.mainpage)}
</div>
</div>
);
}
}

Multiple export with dot notation

I have this code:
Sidebar.jsx
class Sidebar extends Component {
render() {
return (
<div className="sidebar">
{ this.props.children }
</div>
);
}
}
class Item extends Component {
render() {
return (
<div>
<b> { this.props.name } </b>
</div>
);
}
}
export { Sidebar, Item };
index.js
export {default as Header} from './Header';
export {default as Footer} from './Footer';
export {default as Sidebar, Item} from './Sidebar';
app.jsx
import { Sidebar } from '../components';
class App extends Component {
render() {
return (
<div>
<Header/>
<Sidebar>
<Sidebar.Item name='item1' />
<Sidebar.Item name='item2' />
<Sidebar.Item name='item3' />
</Sidebar>
<Footer/>
// ...
The error that I get is:
TypeError: Cannot read property 'Item' of undefined
How I can multiple export component in index.js and call from another file? I'm sure that Header and Footer work correctly because I have only one class in that file.
function Sidebar(props) {
return (
<div className="sidebar">
{ props.children }
</div>
);
}
function Item (props) {
return (
<div>
<b> { this.props.name } </b>
</div>
);
}
Sidebar.Item = {Item}
export default Sidebar
Then you can use it like this
import Sidebar from './Sidebar.js'
...
return (
<Sidebar>
<Sidebar.Item />
</Sidebar>
)
If you're using class based components, you can remove the curly braces
class Sidebar extends Component {
render() {
return (
<div className="sidebar">
{this.props.children}
</div>
);
}
}
class SidebarItem extends Component {
render() {
return (
<div>
<b> {props.name} </b>
</div>
);
}
Sidebar.Item = SidebarItem;
export default Sidebar;
I learned this practice from a coworker that saw it in semantic ui's table here.
Have you tried
import { Item } from '../components';
and then use it:
<Item name='item1' />

Categories

Resources