React unexpected number rendered - javascript

I have the following React example, and I'm trying to show a success toast (from mdbootstrap library) every time the isShowing state is true. This works as expected regarding the toast, but a number is displayed next to the button, and increments after each click. This number also appears as a children of the main div from the App file ( See attached image and codesandbox link) .
Thanks in advance!
import React, { Component } from "react";
import Nav from "./Navbar";
import Routes from "./Routes";
import Mes from "./Message";
import { Button, toast } from "mdbreact";
import "./App.css";
class App extends Component {
state = {
isShowing: false
};
handleClick = () => {
this.setState({
isShowing: true
});
};
render() {
return (
<div className="App">
<Mes />
<Button color="primary" onClick={this.handleClick}>
show Alert{" "}
</Button>
{this.state.isShowing ? toast.success("Success message") : ""}
<Routes />
</div>
);
}
}
export default App;
codesandbox link : https://codesandbox.io/s/l2xqplx4rm

You don't need to render toast.success in your code. Remove
{this.state.isShowing ? toast.success("Success message") : ""}
In above code case your binding the toast's toast.success methods response which is nothing but the active toast length. So its displaying number over there.
Just below code is enough to show toast on button click.
import React, { Component } from "react";
import Nav from "./Navbar";
import Routes from "./Routes";
import Mes from "./Message";
import { Button, toast } from "mdbreact";
import "./App.css";
class App extends Component {
handleClick = () => {
//show toast
toast.success("Success message");
};
render() {
return (
<div className="App">
<Mes />
<Button color="primary" onClick={this.handleClick}>
Show Alert
</Button>
<Routes />
</div>
);
}
}
export default App;
Here is updated code

Related

React - URL gets updated but the page is not rendered

I am following along a beginner's course on React. The Nav. Bar has two options - About, HomePage. On clicking on the bar, the url gets updated but the page remains the same and nav stays. I get no error.
App.js
import React from 'react';
import HomePage from './HomePage';
import About from './About';
import Header from './common/Header';
function App() {
function getPage() {
const route = window.location.pathname;
if (route === "about") return <About />;
console.log("hi");
return <HomePage />;
}
return(
<div className="container-fluid">
<Header>
{ getPage() }
</Header>
</div>
);
}
export default App;
Header.js
import React from 'react';
//to navigate across the website
function Header(){
return (
<nav>
Home | About
</nav>
);
}
export default Header;
index.js
import "bootstrap/dist/css/bootstrap.min.css";
import React from "react";
import {render} from "react-dom";
import App from "./components/App";
render(<App />, document.getElementById("root"));
About.js
import React from 'react';
class About extends React.Component{
render (){
return(
<>
<h1> About </h1>
<p> This is the About Page </p>
</>
);
}
}
export default About;
HomePage.js
import React from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
function HomePage(){
return(
<div className="jumbotron">
<h1>
Welcome
</h1>
<p>
This is my first React Project
</p>
</div>
);
}
export default HomePage;
There is no change in the page, only the URL gets updated.
I have tried many solutions on SO but none worked so far.
I'm guessing it always displays the <HomePage /> component?
That's because window.location.pathname returns a path with a leading slash. So route === "about" will always be false. You need to check route === "/about" instead.
In getPage function condition is wrong it's not about it's will be /about
Just change condition in if statement
like this
if (route === "/about") return <About />;

TypeError: this.props.location.state is undefined -

I have a little problem with my application developed in ReactJS.
Here are my components App.js, AppFront.js and index.js.
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.scss';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>,
document.getElementById('root')
);
serviceWorker.unregister();
App.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import AppFront from './AppFront';
import WizardList from './wizard/WizardList';
import './App.scss';
function App() {
return (
<div className="App">
<Switch>
<Route exact path="/" component={AppFront} />
<Route path="/wizard/:id" component={WizardList} />
</Switch>
</div>
);
}
export default App;
AppFront.js
import React from 'react';
import Wizard from './wizard/Wizard';
function AppFront() {
return (
<div className="AppFront">
<Wizard />
</div>
);
}
export default AppFront;
In the application, I have a "Wizard" folder in which are included the components "dataWizard.js", "Wizard.jsx" and "WizardList.jsx"
folder-structure
The "dataWizard.js" file contains an array of objects.
export const dataWizard = [
{
id: "1",
name: "Harry Potter",
category: "Gryffondor",
text: "Harry is a powerful wizard."
},
{
id: "2",
name: "Drago Malefoy",
category: "Serpentard",
text: "Draco Malfoy is not very brave."
}
The "Wizard.jsx" component loops on this table and transmits the properties with the component of "react-router-dom".
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { dataWizard } from './dataWizard';
import './style/Wizard.scss';
class Wizard extends Component {
render() {
return (
<div className="Wizard">
{
dataWizard.map((wizard, i) =>
<Link
to={{ pathname: `/wizard/${wizard.id}`, state: { wizard } }}
key={i}
>
<span className="name">{wizard.name}</span>
<span className="category">{wizard.category}</span>
</Link>
)
}
</div>
);
}
}
export default Wizard;
I recover the properties without problem with the component "WizardList.jsx".
import React, { Component } from 'react';
import './style/WizardList.scss';
class Wizard extends Component {
render() {
const wizard = this.props.location.state.wizard;
return (
<div className="WizardList">
<div className="container">
<span className="name">{wizard.name}</span>
<span className="category">{wizard.category}</span>
<span className="text">{wizard.text}</span>
</div>
</div>
);
}
}
export default Wizard;
Only when I reload the page, or try to access it directly by typing the path in the URL bar, an error message appears and this.props.location.state is undefined.
Here are some pictures in progressive order to help you better understand my problem.
Homepage - number 1
Information about sorcerer after click - number 2
I am trying to go directly to the informative page on the sorcerer. - number 3
Error message - number 4
Please, I am a beginner, and I have tried several methods seen on the web, but I still cannot resolve this problem. Please, help-me! :)
WizardList gets the data to load from the location.state you are sending it in this Link
<Link
to={{ pathname: `/wizard/${wizard.id}`, state: { wizard } }}
key={i}
>
...but if you refresh in /wizard/:id you have nothing in location.state because you have not followed a link.
However, you have the id of the wizard in the link so you can access it with this.props.match.params.id. Then if there's something in location.state you can use it to load the page but if not, you can take the wizard id and find the proper wizard of the list.
import React, { Component } from 'react';
import { dataWizard } from './dataWizard';
import './style/WizardList.scss';
class Wizard extends Component {
render() {
const wizard = this.props.location ? this.props.location.state.wizard : dataWizard.find(wizard => wizard.id === this.props.match.params.id);
return (
<div className="WizardList">
<div className="container">
<span className="name">{wizard.name}</span>
<span className="category">{wizard.category}</span>
<span className="text">{wizard.text}</span>
</div>
</div>
);
}
}
export default Wizard;

How do I change the innerHTML of an element using React?

I want to change innerHTML of a div, when I click on the button. I don't know why, but instead of getting an error, or getting the expected result it deletes to content and replacing it with "[object Object]".
How can I get it work?
import React from 'react';
import Login from './components/login.js';
import SignIn from './components/signin';
import './App.css';
function App() {
function LoginOnClick(){
document.getElementById("wrapper").innerHTML = <SignIn />;
}
return (
<div className="container" id="wrapper">
<button onClick={LoginOnClick}>Login</button>
<Login />
</div>
);
}
export default App;
You can make use of Hooks (Added n React 16.8).
import React, {useState} from 'react';
import Login from './components/login.js';
import SignIn from './components/signin';
import './App.css';
function App() {
const [signIn, setSignIn] = useState(false);
return (
<div className="container" id="wrapper">
{signIn ? <SignIn /> : <> //This is React Fragments syntax
<button onClick={() => setSignIn(true)}>Login</button>
<Login />
</>
}
</div>
);
}
export default App;
With react you don’t have to set the innerHtml to do this, instead the more typical way is to have internal state in your component and conditionally render your SignIn component based off that. To use state the component either needs to be class or use hooks, classes are more traditional so I changed the component to be a class.
To make a class a react component you need to extend the class with the React.Component, this is because react components have lots of internal behaviours that you need to include with your class for it to be considered a component.
So
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
signIn: false,
};
this.LoginOnClick = () => {
this.setState({ signIn: true });
};
}
render() {
if (this.state.signIn) {
return (
<div className="container">
<SignIn />
</div>
);
}
return (
<div className=“container”>
<button onClick={this.LoginOnClick}>Login</button>
<Login />
</div>
);
}
}
Here is a simple way to do it:
import {useState} from "react";
const App = () => {
const [txt, setTxt] = useState("");
setTxt(<p> 'Lorem ipsum dummy text blabla.' </p>);
return(
<div>
{txt}
</div>
)
}
export default App;

Keep Button on Edge of sidebar

I am in working on a react template, and I want to have a sidebar navigation component. I am struggling with the expanding portion. So when the nav component expands I want the content to shrink and the expand/collapse button to stay on the edge of the menu.
closed
open
My idea was to use react-bootstrap and its Col component, but that did not work. My next idea is to keep track of the width of the sidebar menu and adjust the content and button accordingly. For this idea, I am thinking I need to pull up the width state to my top level component, but that seems sketch. I am trying to figure out how to get the width of a component as it expands and shrinks. My experience is pretty low, this is my first on my own react project.
App.js (top level component)
import React, { Component } from "react";
import { Route, NavLink, HashRouter } from "react-router-dom";
import Home from "./Home";
import SidebarContainer from "./Sidebar/SidebarContainer";
import Row from "react-bootstrap/Row";
export default class App extends Component {
render() {
return (
<HashRouter>
<div>
<Row>
<div className="header">
<span>Company Name</span>
<span>App Name Goes Here</span>
<span>Hello Username</span>
</div>
</Row>
<Row>
<SidebarContainer/>
<div className="content">
<Route exact path="/" component={Home} />
</div>
</Row>
</div>
</HashRouter>
);
}
}
SidebarContainer
import React, { Component } from "react";
import ToggleButton from './ToggleButton';
import SidebarMenu from './SidebarMenu';
export default class SidebarContainer extends Component {
constructor(props) {
super(props);
this.state = {
SidebarOpen: false
};
this.toggleSidebar = this.toggleSidebar.bind(this);
}
toggleSidebar(){
this.setState({
SidebarOpen: !this.state.SidebarOpen
});
}
render(){
return (
<div>
<ToggleButton onClick = {this.toggleSidebar} menuVisibility = {this.state.SidebarOpen}/>
<SidebarMenu menuVisibility = {this.state.SidebarOpen}/>
</div>
)
}
}
Sidebar menu
import React, { Component } from "react";
import "./SidebarMenu.css";
import FeedbackButton from "./FeedbackButton";
export default class SidebarMenu extends Component {
render() {
let visibility = "hide";
if(this.props.menuVisibility){
visibility = "show";
}
return (
<div id="SidebarMenu" className= {visibility}>
<h2>Home</h2>
<h2>About</h2>
<h2>Contact</h2>
<h2>Search</h2>
<FeedbackButton/>
</div>
)
}
};
Button
import React, { Component } from "react";
import "./ToggleButton.css"
export default class ToggleButton extends Component {
render() {
let menuStatus = "hidden";
let direction = ">"
if(this.props.menuVisibility){
menuStatus = "open"
direction = "<"
}
return (
<button id="toggleButton" className={menuStatus} onClick={this.props.onClick}> {direction} </button>
)
}
};

Passing state value from component to component?

I've seen many answer on this website and in official docs and many other places. But I couldn't able to achieve results. That's why I'm posting this question.
SO, my question is I have 3 files named:
App.js, SignUp.js and Welcome.js.
My task is to get value in form from SignUp.js page and print that value to the Welcome.js component. I read about lifting state up and higher order components but couldn't able to do it.
Any help is appreciated.
Here's my code:
App.js:
import React,{Component} from "react";
import {BrowserRouter as Router, Link, Switch, Route} from "react-router-dom";
import SignUp from './SignUp';
import Welcome from './Welcome';
class App extends Component {
render(){
var homeMessage = () =>{
return(<div><SignUp /></div>);
}
return(
<Router>
<div>
<Route exact path="/src/Welcome" component={Welcome}/>
<Route exact path="/" component={homeMessage}/>
</div>
</Router>
);
}
}
export default App;
SignUp.js;
import React,{Component} from "react";
import {Link} from "react-router-dom";
export default class SignUp extends Component {
constructor(props){
super(props);
this.state = {
firstName:''
};
}
inputData = event =>
{
this.setState({
[event.target.name]:event.target.value
});
}
submitData = event =>
{
event.preventDefault();
}
render(){
return(
<div>
<form onSubmit={this.submitData}>
<input type="text" name="firstName" onChange={this.inputData}/>
<button type="submit"> Submit</button>
</form>
<Link to="/src/Welcome">Welcome</Link>
</div>
);
}
}
Welcome.js:
import React,{Component} from "react";
import SignUp from './SignUp';
export default class Welcome extends Component {
render(){
return(
<div>
{this.state.firstName}
</div>
);
}
}
"And please give answer if possible then in react-way only not redux or any other library. Because as per Dan Abramov article "Thinking in React" so first I want to try all scope which is available in react only."
Pass the data back to the parent from SignUp component and then pass it as a prop to the Welcome component. The other way is to store the SignUp component state in the App component so that you don't need to pass it back up when you submit.
App.js
import React,{Component} from "react";
import {BrowserRouter as Router, Link, Switch, Route} from "react-router-dom";
import SignUp from './SignUp';
import Welcome from './Welcome';
class App extends Component {
state = {
firstName: ''
}
onSignIn = (value) => {
this.setState({firstName: value});
}
render(){
return(
<Router>
<div>
<Route exact path="/src/Welcome" render={(props) => <Welcome firstName={this.state.firstName} {...props}/>}/>
<Route exact path="/" render={(props) =>{
return(<div><SignUp onSignIn={this.onSignIn} {...props} /></div>);
}}/>
</div>
</Router>
);
}
}
export default App;
SignUp.js
export default class SignUp extends Component {
constructor(props){
super(props);
this.state = {
firstName:''
};
}
inputData = event =>
{
this.setState({
[event.target.name]:event.target.value
});
}
submitData = event =>
{
event.preventDefault();
this.props.onSignIn(this.state.firstName);
}
render(){
return(
<div>
<form onSubmit={this.submitData}>
<input type="text" name="firstName" onChange={this.inputData}/>
<button type="submit"> Submit</button>
</form>
<Link to="/src/Welcome">Welcome</Link>
</div>
);
}
}
Welcome.js
import React,{Component} from "react";
import SignUp from './SignUp';
export default class Welcome extends Component {
render(){
return(
<div>
{this.props.firstName}
</div>
);
}
}
Some useful links:
How to pass data from child component to its parent in ReactJS?
Passing custom props to router component in react-router v4
ReactJS - Lifting state up vs keeping a local state

Categories

Resources