Route to another page on click button reactjs - reactjs

Am new to reactjs and now working on routing and navigation. On pressing button am trying to navigate to new page, but it throws error.
my App.js file:
import React from 'react';
import './App.css';
import Editor from './editor';
import {BrowserRouter as Router, Route, Link} from "react-router-dom";
import {createBrowserHistory} from "history";
const history = createBrowserHistory();
class App extends React.Component {
constructor(props) {
super(props);
this.state ={
};
this.onProductClick = this.onProductClick.bind(this);
}
onProductClick(){
console.log('clicked');
this.history.push('/editor');
}
render() {
return (
<Router>
<div>
<Route path='/editor' component={Editor} history={history} />
</div>
<div>
<button onClick={this.onProductClick} className="btn btn-primary" id="a_1">Try now!</button>
</div>
</Router>
)
}
}
export default App;
And my editor.js file is this:
import React, { Component } from 'react';
class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
return (
<div id="editor">
<h3>Products Here</h3>
</div>
);
}
}
export default Editor;
after clicking the button the error message is:
TypeError: Cannot read property 'push' of undefined
15 | }
16 | onProductClick(){
17 | console.log('clicked');
> 18 | this.history.push('/editor');
19 | ^
20 | }
21 |
22 | render() {
I don't Understand what am doing wrong here.

It looks like your referencing this.history.push('/editor'); inside of onProductClick, because you are using this, the JS engine is trying to find the variable history in the context of the class but since there's no variable called history defined within the class's context it's evaluating to undefined.push leading to the error cannot read property push of undefined.
You did define a history variable outside of the class definition. To access it, you can change this.history.push('/editor'); to history.push('/editor'); with this change, you will be referencing the history variable you defined on the top.
Most likely however with React router, you should try to access the history object from props, so this.props.history.push('/editor')

The history object is available in the props. Use this.props.history.push instead. Also, there are a couple of things wrong about your code. Try isolating the routes and components. The button must be outside the router component. Use React.Fragment to render more than two components at once. Study up some more about react.

Related

How to navigate from one component to another by clicking a button using React router

I want to use react-router-dom to navigate my website.
Every component will render <button> whenever onClick will active the switch to the next component.
Main component Login.js will contain all the 4 components inside it.
I need to know what are the ways to do it.
(The first time user must not skip the login process below anyhow)
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Redirect,
Route,
Switch,
} from 'react-router-dom';
import MobileNum from './MobileNum.jsx';
import IdNumber from './IdNum.jsx';
import userEmail from './userEmail';
import CreatePass from './createPassword .jsx';
class Login extends Component {
render() {
return (
<div>
<button onClick={}></button>
</div>
);
}
}
To redirect the user you want to call push on the history object. To get the history object in a class component you can use the withRouter higher-order component, e.g.
class Login extends Component {
render() {
const { history } = this.props;
return (
<div>
<button onClick={() => history.push('foo')}>Login</button>
</div>
);
}
}
export const LoginWithRouter = withRouter(Login);
Source: https://dev.to/kozakrisz/react-router---how-to-pass-history-object-to-a-component-3l0j

React Route shows up a blank page

I am creating a MERN project in webstorm. I am trying to direct to another React component upon clicking a button in one React component. I did that using Routes. Redirection happens. But the content in my second React component is not showing up.
<Button block bsSize="large" disabled={!validateForm()} type="submit">
{/* eslint-disable-next-line no-undef */}
<Route path = "./" component = {AppointmentMakingComponent} />
</Button>
My second React component is
import React from 'react'
class Hello extends React.Component {
constructor(props){
//Since we are extending the default constructor,
//handle default activities first.
super(props);
//Extract the first-name from the prop
let firstName = "abc"
//In the constructor, feel free to modify the
//state property on the current context.
this.state = {
name: firstName
}
} //Look maa, no comma required in JSX based class defs!
render() {
return <h1>Hello, {this.state.name}!</h1>
}
}
export default Hello
Please help

TypeError: undefined is not an object (evaluating 'undefined.state') with React-router-dom

I am learning to develop a multi-page app with React Router. I have been following a tutorial and have managed to set up multiple page without any content. However, I want to add the original main content of the home page that was originally running properly before I used react-router. If I delete the code that is in the div called App, I have added in Home.js, then I can go back to switching between blank pages with no errors:
import React from 'react';
//import "./App.css";
import List from "./List";
import Title from "./Title";
import Ending from "./Ending";
import MoviePage from "./MoviePage";
const home = () => {
return (
<div className="App">
<Title pics={this.state.pics} changePageNumber={this.changePageNumber}/>
<List parentCallback={this.loadMoviePage} movieList={this.state.movieList}/>
<Ending toad={this.state.toad} speedUp={this.state.speedUp}/>
</div>
);
}
export default home;
So I know that I am not able to access the content from this.state.pics.(Nor the other 3 components). I created this content(and by content I mean the arrays that have the general information, i.e image location, etc). in App.Js so I am wondering how can I pass it in to this new Home.js file?
You can not access state in stateless component , if you need some data from another component you need to pass it as props from parent to children , just to show you i just make an example of your code follow it, you will get it
App.js
import React from 'react';
import Home from "./Home";
class App extends Component {
constructor() {
super();
this.state = {
pics: YourArrayDataHere,
};
}
render () {
return (
<Home pics={this.state.pics} />
);
}
export default App;
Home.js
import React from 'react';
//import "./App.css";
import List from "./List";
import Title from "./Title";
import Ending from "./Ending";
import MoviePage from "./MoviePage";
const home = (props) => { //access throught props
return (
<div className="App">
<Title pics={props.pics} />
</div>
);
}
export default home;

Why it shows the error: Error: Target container is not a DOM element, when creating a ReactDOM.createPortal() and pass a const variable

On a tutorial about ReactJS and context API, I was trying to render a Modal class by creating a const inside a class extended by React.Component
import React from 'react';
import ReactDOM from 'react-dom';
import './style.scss';
import { AppContext } from '../../context/appContext';
class Modal extends React.Component {
render() {
const node = (
<div
className="modal-container">
<div className="modal">
<h1>modal</h1>
</div>
</div>
);
return ReactDOM.createPortal(node, document.getElementById('modal'));
}
}
Modal.contextType = AppContext;
export default Modal;
And using this class on a layout class also extended of React.Component and using the ReactDOM by
import Modal from '../modal';
<Modal />
But when I tried to render it, it gave me the error that the const node I created, it's not a DOM element, also on the tutorial I followed to do this, he hasn't any error.
Error: Target container is not a DOM element.
createPortal$$1 [as createPortal]
> 17 | return ReactDOM.createPortal(node, document.getElementById('modal'));
View compiled
▶ 16 stack frames were collapsed.

React-router custom prop not passing to component. ternary operator not working correctly

In React i have my App.js page where i keep my states. I'm importing user1.js component to App.js, and in user1.js component i have a link button that takes me to path /user2.
When i click the button, React will set state property called testValue to true and in user2.js page ternary operator should choose the first value - test works because of that. But for some reason it does not work.
Any help?
APP.JS
import React, { Component } from 'react';
import './App.css';
import User1 from './components/user1';
class App extends Component {
constructor(props){
super(props);
this.state = {
testValue:false
};
}
change = () => {
this.setState({
testValue:true
},() => {
console.log(this.state.testValue)
});
}
render() {
return (
<div className="App">
<User1 change={this.change}/>
</div>
);
}
}
export default App;
USER1.JS
import React from 'react';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import User2 from './user2.js';
const User1 = (props) => {
return(
<BrowserRouter>
<div>
<Link to ="/user2">
<button onClick={props.change}>Next page</button>
</Link>
<Switch>
<Route path="/user2" exact component={User2}/>
</Switch>
</div>
</BrowserRouter>
); // end of return
};
export default User1;
USER2.JS
import React from 'react';
const User2 = (props) => {
console.log(props)
return(
<div>
{props.testValue ?
<p>test works</p>
:
<p>test does not work</p>
}
</div>
);
};
export default User2;
This is what i expected - test works
This is what i got - test does not work
You want to pass a custom property through to a component rendered via a route. Recommended way to do that is to use the render method.
<Route path="/user2" exact render={(props) => <User2 {...props} testValue={true} />} />
I think a valid inquiry here would be what are you wanting to pass through as an extra prop? whats the use case here? You may be trying to pass data in a way you shouldn't (context would be nice :D).

Resources