EDIT: Events are not working at all, the onSubmit and onChange functions are not being called. I have another reactapp with similar form and onChange and onSubmit works OK there.
I have a form I dont want the page to refresh when I click on submit. I tried using preventDefault() but I didnt work. Even onChange is printing anything on console. This form is not on page, I am using React Router to point to='/new' and component={NewPost} (NewPost is in ./components/posts/form)
./components/posts/form.js:
import React, { Component } from "react";
import { connect } from "react-redux";
class NewPost extends Component {
state = {
title: "",
body: "",
status: 0,
};
onSubmit = (e) => {
e.preventDefault();
const post = e;
console.log(post);
};
onChange = (e) => {
console.log(e.target.value);
this.setState({
[e.target.name]: e.target.value,
});
};
render() {
const { title, body, status } = this.state;
return (
<div className="card card-body mt-4 mb-4">
<h2>New Post</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Title</label>
<input
type="text"
name="title"
value={title}
onChange={this.onChange}
className="form-control"
/>
</div>
<div className="form-group">
<label>Content</label>
<textarea
type="text"
name="body"
rows="15"
value={body}
onChange={this.onChange}
className="form-control"
/>
</div>
<div className="form-group">
<button className="btn btn-primary" type="submit">
Submit
</button>
</div>
</form>
</div>
);
}
}
export default NewPost;
App.js:
import React from "react";
import NavBar from "./components/layout/navbar";
import store from "./store";
import { Provider } from "react-redux";
import Dashboard from "./components/posts/dashboard";
import NewPost from "./components/posts/form";
import {
HashRouter as Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
class App extends React.Component {
render() {
return (
<Provider store={store}>
<Router>
<React.Fragment>
<div className="container">
<NavBar />
<Switch>
<Route exact path="/" component={Dashboard}></Route>
<Route exact path="/new" component={NewPost}></Route>
</Switch>
</div>
</React.Fragment>
</Router>
</Provider>
);
}
}
export default App;
Issue is not related to code. I created new react application and moved all my code now everything is working fine.
Related
when the user fills the sing up form and clicks the sing up button it has to be two scenarios
first: if the password and confirm password is matching it has to route to the dashboard page
second: if the password and confirm password is not matching it has to alert a massage ("Passwords do not match")
mine I used condition at Log.jsx down below for a function called handlesubmit , in that condition the first part of the condition is not working but the second part of the condition that regarding the second scenario is working and alerting the massage
here is my code and some screenshots
Log.jsx
import React from "react";
import "./log.css";
import { useState } from "react";
import { Link } from "react-router-dom";
export default function Log() {
const [formData, setFormData] = useState({
fullName: "",
email: "",
password: "",
passwordConfirm: "",
});
function handleChange(event) {
const { name, value } = event.target;
setFormData((prevFormData) => ({
...prevFormData,
[name]: value,
}));
}
function handleSubmit(event) {
event.preventDefault();
if (formData.password === formData.passwordConfirm) {
return (
<Link className="link" to={"/Dashboard"}>
</Link>
);
} else {
alert("Passwords do not match");
return;
}
}
return (
<div className="loginn">
<div className="login-items">
<div className="title-log">
<p className="login-title">sing up</p>
</div>
<form className="form" onSubmit={handleSubmit}>
<span className="fullname">Fullname</span>
<input
className="input-lg"
type="name"
placeholder="Email address"
name="fullName"
onChange={handleChange}
value={formData.fullName}
></input>
<span className="email">Email</span>
<input
className="input-lg"
type="email"
name="email"
onChange={handleChange}
value={formData.email}
></input>
<span className="password">Password</span>
<input
className="input-lg"
type="password"
name="password"
onChange={handleChange}
value={formData.password}
></input>
<span className="password">Confirm Password</span>
<input
className="input-lg"
type="password"
name="passwordConfirm"
onChange={handleChange}
value={formData.passwordConfirm}
></input>
<button className="login-btn">Sing up</button>
</form>
</div>
</div>
);
}
Home.jsx
import React from 'react'
import Naav from '../../components/naav/Naav'
import Log from '../../components/log/Log'
import Footer from '../../components/footer/Footer'
export default function Home() {
return (
<div className='home'>
<Naav/>
<Log/>
<Footer/>
</div>
)
}
Dashboard.jsx
import React from "react";
import "./dashboard.css"
import Sidebar from "../../components/sidebar/Sidebar";
import Navtwo from "../../components/navtwo/Navtwo";
import Cards from "../../components/cards/Cards";
import Data from "../../components/data/Data";
import Title from "../../components/title/Title";
export default function Dashboard() {
return( <div className="dashboard">
<Sidebar/>
<Navtwo/>
<Title/>
<Cards/>
<Data/>
</div>
)
}
app.js
import React from "react";
import "./app.css";
import Headerr from "./components/headerr/Headerr";
import Naav from "./components/naav/Naav";
import Footer from "./components/footer/Footer";
import Log from "./components/log/Log";
import Sidebar from "./components/sidebar/Sidebar";
import Navtwo from "./components/navtwo/Navtwo";
import Cards from "./components/cards/Cards";
import Title from "./components/title/Title";
import Data from "./components/data/Data";
import Dashboard from "./pages/dashboard/Dashboard";
import Home from "./pages/home/Home";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
export default function App() {
const currentUser = false;
return (
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/Dashboard" element={<Dashboard />} />
</Routes>
</Router> );
}
In your handleSubmit function, you return the Link component.
That does nothing!
There are 2 ways you can go about here.
Create a state passwordMatch, and set it inside handleSubmit. If the passwords do not match, return the Redirect element instead of the form.
Import the history and call it to navigate where you want inside the handleSubmit
I use Laravel as backend and ReactJS as frontend. In ReactJS, create Routes.
In Laravel, create Api. When I parse the Parameter from ReactJS to Laravel, First time okay. After I reload these page, show Json Only
I tried Parameter Route like this "/:id" and work. But for multiple Objects it did not solve. It work for only one Object.
App.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Route, Switch, browserHistory,IndexRoute } from 'react-router-dom'
import NewApp from './NewApp'
import AppList from './AppList'
import NAVBAR from './NAVBAR'
import Container from './Container'
import MainNavigation from './MainNavigation'
import AppSettingList from './AppSettingList'
import UpdateApp from './UpdateApp'
import {withRouter} from 'react-router';
class App extends Component {
render () {
console.log(window.location.pathname);
return (
<BrowserRouter>
<div>
{/* <Header /> */}
<NAVBAR />
<MainNavigation />
<Switch>
<Route exact path='/' component={withRouter(Container)} />
<Route exact path='/dashboard/' component={withRouter(Container)} />
<Route exact path='/app/' component={withRouter(AppList)} />
<Route exact path='/app/:id' component={withRouter(UpdateApp)} />
<Route exact path='/appsetting/' component={withRouter(AppSettingList)} />
<Route exact path='/app/create' component={withRouter(NewApp)} />
</Switch>
</div>
</BrowserRouter>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
UpdateApp.js
import axios from 'axios'
import React, { Component } from 'react'
import NiftySuccessModal from './alerts/NiftySuccessModal'
class UpdateApp extends Component {
constructor (props) {
super(props)
this.state = {
name: '',
description: '',
errors: [],
apps : [],
id : 0,
loading : false,
successModal : false
};
// binding
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.hasErrorFor = this.hasErrorFor.bind(this);
this.renderErrorFor = this.renderErrorFor.bind(this);
this.showSuccessModal = this.showSuccessModal.bind(this);
this.getApp = this.getApp.bind(this);
this.gotoApp = this.gotoApp.bind(this);
}
getApp(appId){
axios.get(`/app/${appId}`).then(response => { // return value
this.setState({
apps: response.data.apps,
name : response.data.apps.name,
id : response.data.apps.id
});
console.log(response.data.apps);
});
}
componentDidMount () {
const appId = this.props.match.params.id;
this.getApp(appId);
}
gotoApp(){
this.props.history.push('/app');
}
handleChange(e){
this.setState({
name: e.target.value
});
}
showSuccessModal(e){
this.setState({
successModal : true
});
setTimeout(() => {
this.setState({
successModal: false
})
}, 10000);
}
hasErrorFor (field) {
return !!this.state.errors[field]
}
renderErrorFor (field) {
if (this.hasErrorFor(field)) {
return (
<span className='invalid-feedback'>
<strong>{this.state.errors[field][0]}</strong>
</span>
)
}
}
handleSubmit(e){
e.preventDefault();
const params = {
id : this.state.id,
name: this.state.name
}
console.log('Update');
axios
.post('/app/update', params)
.then(response => {
console.log('Success');
})
.catch(error => {
console.log('Error');
this.setState({
errors: error.response.data.errors
});
})
}
render () {
return (
<div id="content-container">
<div id="page-head">
<div className={"pad-all text-center"}>
<h3>Welcome back to the Dashboard.</h3>
<p>Scroll down to see quick links and overviews of your Server, To do list, Order status or get some Help using Nifty.</p>
</div>
</div>
<div id="page-content">
<div className={"row"}>
<div className={"col-md-1"}></div>
<div className={"col-lg-9"}>
<NiftySuccessModal show={this.state.successModal} > Successfully Updated! </NiftySuccessModal>
<div className={"panel"}>
<div className={"panel-heading"}>
<h3 className={"panel-title"}>App </h3>
</div>
<form className={"panel-body form-horizontal form-padding"} onSubmit={this.handleSubmit}>
<div className={"form-group"}>
<label className={"col-md-3 control-label"} >App Name</label>
<div className={"col-md-9"}>
<input type="text"
name='name'
id='name'
onChange={this.handleChange}
value={this.state.name}
className={"form-control"}
maxLength="255"
placeholder="App Name..."
required className={"form-control"} placeholder="Text" />
<small className={"help-block"}>This is a help text</small>
</div>
</div>
<div className={"form-group demo-nifty-btn col-md-3"}>
<input type="submit" onClick={this.showSuccessModal} value="Update" className={"form-control btn btn-primary"} />
</div>
</form>
</div>
</div>
</div>
</div>{/* End <!--Page content--> */}
</div> // End <!--CONTENT CONTAINER-->
)
}
}
export default UpdateApp
![Before Reload]: (https://i.imgur.com/rWqFo9Y.png)
![After Reload]: (https://i.imgur.com/maR3x1S.png)
Now Solved! using difference route name and Query Strings with React Router. Page Reload also okay. Thanks.
that is not working
<Route path='/app' component={withRouter(AppList)} />
<Route path='/app/:id' component={withRouter(UpdateApp)} />
working with Query String
<Route path='/updateapp' component={withRouter(UpdateApp)} />
For some reason, my web app is not directing to the component whenever I go to the parameters. Specifically, it is not going to the Battle component.
Here is what the navigation looks:
import React from 'react';
import Header from './components/Header/Header';
import SelectPlayers from './pages/SelectPlayers/SelectPlayers';
import Popular from './pages/Popular/Popular'
import Battle from './pages/Battle/Battle'
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
function App() {
return (
<Router>
<div className={'flex flex-column'}>
<Header />
<Switch>
<Route exact path={'/'} component={Popular}/>
<Route exact path={'/battle/select-player'} component={SelectPlayers} />
<Route exact path={'/results?playerOne=:playerOne&playerTwo=:playerTwo'} component={Battle} />
</Switch>
</div>
</Router>
);
}
export default App;
In the SelectPlayers component, whenever the user presses a button it runs:
import React, {useState} from 'react';
function SelectPlayers(props) {
const [playerOne, setPlayerOne] = useState('');
const [playerTwo, setPlayerTwo] = useState('');
function setPlayerName(event, player){
if (player === 1){
setPlayerOne(event.target.value)
} else if (player === 2) {
setPlayerTwo(event.target.value)
}
}
function goToBattle(event){
event.preventDefault();
props.history.push(`/results?playerOne=${playerOne}&playerTwo=${playerTwo}`)
}
return (
<div className={'pa3 mh7-l mh7-m'}>
<div className="flex flex-column">
<div className={'mb1'}>
<h1 className={'mb0'}>Player One</h1>
<input onChange={(e) => setPlayerName(e, 1)} type="text" placeholder={'github username'} className={'input-reset pa1 w-100 h2 ba b--black br2'}/>
</div>
<div className="tc dark-red">
<h1>Versus</h1>
</div>
<div className={'mb3'}>
<h1 className={'mb0 mt0 tr'}>Player Two</h1>
<input onChange={(e) => setPlayerName(e, 2)} type="text" placeholder={'github username'} className={'input-reset pa1 w-100 h2 ba b--black br2'}/>
</div>
<div>
<button onClick={(e) => goToBattle(e)} className={'input-reset pa1 h2 fw1 bg-black white ba w-100 b--black br2'}>Battle</button>
</div>
</div>
</div>
);
}
export default SelectPlayers;
On the Battle component, I write some console.log stuff just to check if the Component loaded. However, whenever I go to that parameter, none of the code in my componentDidMount is running. I don't see any of the console.logs I wrote in componentDidMount in my developer console. Here is the component:
import React, {Component} from 'react';
class Battle extends Component {
constructor(props){
super(props)
}
componentDidMount() {
console.log('runngins');
console.log(this.props);
}
render() {
return (
<div className={'pa3 mh7-l mh7-m'}>
<div className="flex flex-column">
</div>
</div>
);
}
}
export default Battle;
You can see the code at this repo: https://github.com/tarekgabarin/github_compete
It would be greatly appreciated if anyone helped me.
As per your new comment that code is working without queryset, looks like there is some problem with your queryset parameters.
As suggested in comment box, don't define Router with queryset.
<Switch>
<Route exact path={'/'} component={Popular}/>
<Route exact path={'/battle/select-player'} component={SelectPlayers} />
<Route exact path={'/results'} component={Battle} />
</Switch>
In your SelectPlayers component, navigate to next page with queryset.
props.history.push("/results?playerOne=" +playerOne+ "&playerTwo=" +playerTwo)
On Battle component, use (query-string) to read the parameter. For example:
const values = queryString.parse(this.props.location.search);
const player_one = values.playerOne
const player_two = values.playerTwo
Please note that my above code is not tested.
Thanks
I have the following piece of code in my parent component:
class App extends Component {
render() {
return(
<Router>
<div>
<Route exact path='/' component={Main} />
<Route path="/login" component={Login} />
</div>
</Router>
);
}}
And this in Main component:
import React, { Component } from "react";
import {BrowserRouter as Router, Route, Link } from 'react-router-dom'
class Main extends Component {
render() {
return (
<Router>
<section className="section main">
<div className="container">
<div className="main-titles-container">
<div className="main-titles">
<div className="yellow-square"></div>
<h1>Title</h1>
<p>
Introduction
</p>
<div className="button-container">
<Link to='/login' className="btn select bg-yellow" id="buyer">Next</Link>
</div>
</div>
</div>
</div>
</section>
</Router>
);
}
}
export default Main;
Login:
import React, { Component } from 'react';
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: "",
cellphone: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
const target = e.target;
this.setState({
[target.name]: target.value
});
}
handleSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render() {
return (
<section className="section">
<div className="container center center-xy">
<h1 className="title center-self">Title</h1>
<h1 className="title center-self">Log in</h1>
<div className="form-container">
<form onSubmit={this.handleSubmit}>
<label htmlFor="email">Email</label>
<input type="text" name="email" id="email" onChange={this.handleChange} defaultValue="" required/>
<label htmlFor="cellphone">Cell phone</label>
<input type="text" name="cellphone" id="cellphone" defaultValue="" onChange={this.handleChange} required/>
<button className="bg-yellow center-self" type="submit">Ok</button>
</form>
</div>
</div>
</section>
);
}
}
export default Login;
On click I want to be redirected to Login page, but the problem is that when i click on that 'button' the URL is changed to '/login', but the corresponding component isn't rendered. However, if I refresh the page with that '/login' url the component is rendered.
Thanks for any help in advance!
EDIT: I'm not using PureComponent and wrapping exports in withRouter doesn't solve my problem too.
You should only have the top-level component (in your case, App) rendering the Router component. All of the components under that (ex. Main) should not have a Router in the render function. They will inherit the parent's Router. You can still use Link or Route components inside of the child components and they will navigate the parent Router.
I´m learning in react and practicing making a simple application to login and view messages sent.
I´ve read a lot about routing, links and redirect, but i couldn´t translate to my app.
I Would like to click in the "Login" button of a component and redirect to another component.
Here i have the principal component : App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
class Login extends Component {
state = {
loggedIn:false
};
loginHandle = () => {
this.setState({loggedIn:true});
}
render(){
return (
<div className="container d-flex h-100">
<div className="row align-self-center w-100">
<div className="col-6 mx-auto">
<div className="jumbotron">
<form name="form1">
<fieldset>
<legend>Chat App</legend>
<label for="UserName" className="col-form-label">Username</label>
<input type="text" className="form-control col-12" id="UserName"></input>
<label for="Password" className="col-form-label">Password</label>
<input type="text" className="form-control col-12" id="Password"></input>
<button type="button" value="log in" className="btn btn-secondary" onClick={this.loginHandle}>Login</button>
</fieldset>
</form>
<div style={{float:"right"}}>
<div className="login-help ">
Register - Forgot Password
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
I wrapped all the Links in a Navigation component
So, when i route /, it goes to the Login component
class Login extends Component {
state = {
loggedIn:false
};
loginHandle = () => {
this.setState({loggedIn:true});
}
render(){
return (
<div className="container d-flex h-100">
<div className="row align-self-center w-100">
<div className="col-6 mx-auto">
<div className="jumbotron">
<form name="form1">
<fieldset>
<legend>Chat App</legend>
<label for="UserName" className="col-form-label">Username</label>
<input type="text" className="form-control col-12" id="UserName"></input>
<label for="Password" className="col-form-label">Password</label>
<input type="text" className="form-control col-12" id="Password"></input>
<button type="button" value="log in" className="btn btn-secondary" onClick={this.loginHandle}>Login</button>
</fieldset>
</form>
<div style={{float:"right"}}>
<div className="login-help ">
Register - Forgot Password
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
Do i have to import routes and redirect in the Login component, or i have to mange all from the App component?
Sorry about this mess, but i don´t know how to continue
Thanks a lot. I really apreciatted in advance.
The simplest way for navigating to another route.
For example you can wrap your Forgot password like following:
<Link to="/forgotRoute">Forgot password?</Link>
Don't forget to add /forgotRoute handling into your Navigator config (where you routed / to your Login component).
Hope it helps.
The correct way for what you want i think it is. So follow me..
You need to use router. In my case i'm using react-router-dom.
First router App component, by default page its renders DefaultPage components and in DefaultPage when component mounted you can render client anywhere.
index.js looks like:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Route, Switch } from 'react-router-dom';
class DefaultPage extends Component {
state = {
autorized: false,
mounted: false,
}
componentDidMount = () => {
const { autorized } = this.state;
if (!autorized) {
this.props.history.push('/login');
return;
}
this.setState({
mounted: true,
});
}
render = () => {
if (!this.state.mounted) {
return (
<React.Fragment>
<p>Waiting...</p>
</React.Fragment>
)
}
return (
<React.Fragment>
<p>Hello...</p>
</React.Fragment>
)
}
}
class Login extends React.Component {
handleLogin = () => {
if (contidion) {
this.props.history.push('/');
}
}
render = () {
return (
<button onClick={this.handleLogin}>Click to login</button>
)
}
}
class App extends React.Component {
render = () {
return (
<Switch>
<Route exact path="/" component={DefaultPage} />
<Route path="/login" component={Login} />
<Route component={DefaultPage} />
</Switch>
)
}
}
ReactDOM.render(
<BrowserRouter >
<App />
</BrowserRouter>,
document.getElementById("root")
);