What is v-if in react? I tried this but My div with loading class does not work when the loading data changes, so the div doesn't re-render itself.
codes is here:
{
loading &&
<div className="loading"></div>
}
I'm changing loading with a function, this function working with onclick event.
all of my code:
import React from "react";
import axios from "axios";
export class LoginPage extends React.Component{
render(){
let username = '',
password = '',
loading = false
function login(){
loading = true;
console.log(loading)
}
return (
<div className="App">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"
integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA=="
crossOrigin="anonymous" referrerpolicy="no-referrer"/>
{
loading &&
<div className="loading"></div>
}
<div className="login">
<h1>Login/Register</h1>
<div>
<i className="fas fa-user"></i>
<input type="text" onChange={(e) => username = e.target.value} placeholder="Username" maxLength="15"/>
</div>
<div>
<i className="fas fa-lock"></i>
<input type="Password" placeholder="Password" onChange={(e) => password = e.target.value} maxLength="18"/>
</div>
<button onClick={() => login()}>Login/Register</button>
</div>
</div>
);
}
}
I'd suggest you read about React State, some things in this piece of code are wrong. But let's fix your problem.
First add this variable to the state and then change it with setState, to trigger a rerender:
export class LoginPage extends React.Component{
constructor(props) {
super(props);
this.state = {
loading: false
};
}
login(){
this.setState({ loading: true })
console.log(this.state.loading)
}
render(){
let username = '',
password = '',
// your return will stay the same
}
}
Related
I have a simple login form component that when I click, would like for the form to disappear and only display my json. I am a little rusty with working with react state, and appear to have the opposite effect of what I am trying. When I click on my button event, the json I am displaying will toggle appearing and disappearing, but the form stays static. I need the form to disappear and the page to populate with my grid.
Here is my components
index.jsx
import React from 'react';
import SignUp from '../SignUp';
import Cards from '../Articles/Cards';
export default class Gecko extends React.Component {
constructor(props) {
super(props);
this.state = { requestedPostsThatWeGotFromGecko: null, }
this.clickMe = this.clickMe.bind(this)
}
clickMe = () => {
const {requestedPostsThatWeGotFromGecko} = this.state;
this.setState({ requestedPostsThatWeGotFromGecko: !requestedPostsThatWeGotFromGecko })
}
render() {
console.log(this.state);
return (
<div className='gecko'>
<SignUp login={() => this.clickMe()}/>
{this.state.requestedPostsThatWeGotFromGecko &&
<Cards />
}
</div>
);
}
}
Sign up component
import React from 'react';
export default class SignUp extends React.Component {
render() {
const onClick = () => {
this.props.login();
console.log('rich');
}
return (
<div className='sign-up'>
<table className='sign-up-form'>
<tbody>
<div class="gecko-signup__tabs"><button id="gecko-signup" data-selected="yes">Sign Up</button><button id="gecko-login" data-selected="">Log In</button></div>
<tr>
<td>
<p id="signUpFree">Sign Up for Free</p>
</td>
</tr>
<div id="inputs-section">
<tr>
<td><input id="first" placeholder="First Name*" /></td>
<td><input id="last" placeholder="Last Name*" /></td>
</tr>
</div>
<tr>
<td colSpan="2"><input placeholder="Email Address*" /></td>
</tr>
<tr>
<td colSpan="2"><input placeholder="Set A Password*" /></td>
</tr>
<tr>
<td colSpan="2"><input id="getStarted" type="submit" value="Get Started" onClick={onClick}/></td>
</tr>
</tbody>
</table>
</div>
);
}
}
CardSetup component
import React from 'react';
import SignUp from '../SignUp';
export default class Articles extends React.Component {
constructor(props) {
super(props);
this.state = {
requestedPostsThatWeGotFromGecko: [],
}
}
componentDidMount(){
const api = 'https://5d445466d823c30014771642.mockapi.io/api/v1/products';
const request = new Request(api);
// Fetch isn't browser compatible...Might should fix.
fetch(request)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Something went wrong on api server!');
};
}).then(response => {
this.setState({
requestedPostsThatWeGotFromGecko: response
});
})
.catch(error => {
console.error(error);
});
}
render() {
return(
<div className='articles'>
{this.state.requestedPostsThatWeGotFromGecko.map(product => {
return (
<div className='flex-grid'>
<div className="card">
<div className="overflow">
<img className='productImage' src={product.image}></img>
</div>
<div className='card-body'>
<p id='name'>{product.name}</p>
<p id='description'>{product.description}</p>
<p id='price'>{product.price} </p>
</div>
</div>
</div>
);
})
}
</div>
)}}
Final Cards component
import React from 'react';
import Articles from './CardSetup';
export default class Cards extends React.Component {
render() {
return(
<div className="cards">
<h2>Products</h2>
<div className="column">
<Articles />
</div>
<div className="column">
<Articles />
</div>
<div className="column">
<Articles />
</div>
<div className="column">
<Articles />
</div>
</div>
);
}
}
I am pretty sure that I am setting the state incorrectly somewhere along the line after I press the button. I am thinking about jquery and wanting to "hide" the element but I know that is incorrect with react. Any help is greatly appreciated.
Conditionally render Cards or Signup based on truthy/falsey value of requestedPostsThatWeGotFromGecko.
render() {
const { requestedPostsThatWeGotFromGecko } = this.state;
return (
<div className="gecko">
{requestedPostsThatWeGotFromGecko ? (
<Cards />
) : (
<SignUp login={() => this.clickMe()} />
)}
</div>
);
}
Probably this is what you want:
render() {
return (
<div className='gecko'>
{!this.state.requestedPostsThatWeGotFromGecko &&
<SignUp login={() => this.clickMe()}/>
}
{this.state.requestedPostsThatWeGotFromGecko &&
<Cards />
}
</div>
);
}
If I understood correctly, you want to toggle between the Signup form and Cards based on requestedPostsThatWeGotFromGecko state variable.
So you can do something like this in your index.jsx:
render() {
return (
<div className='gecko'>
{this.state.requestedPostsThatWeGotFromGecko ?
<Cards /> :
<SignUp login={() => this.clickMe()} />
}
</div>
);
}
All you have to do is conditionally render the SignUp page on the basis of flag requestedPostsThatWeGotFromGecko.
Note: Important thing is you have to initialize it with false and make it true on the click from the SignUp page.
constructor(props) {
super(props);
this.state = { requestedPostsThatWeGotFromGecko: false };
this.clickMe = this.clickMe.bind(this)
}
render() {
const { requestedPostsThatWeGotFromGecko } = this.state;
return (
<div className="gecko">
{requestedPostsThatWeGotFromGecko ? (
<Cards />
) : (
<SignUp login={() => this.setState({ requestedPostsThatWeGotFromGecko: true })} />
)}
</div>
);
}
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)} />
I do not use html in form, because when I use and I click on <button type = "button" className = "button button2" onClick = {() => this.login ()}> logar </ button>, the page of a refresh and the error message some. But when I do not use it, this message appears to me in the console: [DOM] Password field is not contained in a form: (More info: https :// goo.gl/9p2vKq)
import React, {Component, Fragment} from 'react'
import {Redirect} from 'react-router-dom'
import { connect } from 'react-redux'
import ActionCreator from '../redux/actionCreators'
import styled from 'styled-components'
import Button from './elements/Button'
const BodyLogin = styled.div`
#formulario{
max-width: 850px
}`
import {Redirect} from 'react-router-dom'
class ScreensLogin extends Component {
constructor(props){
super(props)
this.state = {
form: {
email: '',
passwd: '',
}
}
}
componentDidMount(){
if (this.props.auth.error){
this.props.reset()
}
}
handleChange = field => event => {
const form = {
...this.state.form
}
form[field] = event.target.value
this.setState({form})
}
login = () => {
const {email, passwd} = this.state.form
this.props.login(email, passwd)
}
render(){
return (
<Fragment>
<BodyLogin>
<form> //this is my problem
<div className='form-group mx-auto' id="formulario">
<div className="input-group">
<div className="input-group-prepend">
<span className="input-group-text" id="">Email</span>
</div>
<input className="form-control" autoComplete='on' value={this.state.form.email} type="text" onChange={this.handleChange('email')} ></input>
</div>
<div className="input-group mt-5 mb-5">
<div className="input-group-prepend">
<span className="input-group-text" id="">Senha</span>
</div>
<input className="form-control" autoComplete='on' value={this.state.form.passwd} type="password" onChange={this.handleChange('passwd')} ></input>
</div>
<Button>
{<button type="button" className="button button2 " onClick={() => this.login()}>logar</button>}
</Button><br/><br/>
{this.props.auth.isAuth && <Redirect to={'/'}/>}
{
this.props.auth.error && <p className="text-danger">{this.props.auth.errorMessage}</p>
}
{
this.props.auth.isSigningin && <p className="text-info">Carregando...</p>
}
</div>
</form>
</BodyLogin>
</Fragment>
)
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
}
const mapDispatchToProps = dispatch => {
return {
login: (email, passwd) => dispatch(ActionCreator.signinRequest(email,passwd)),
reset: () => dispatch(ActionCreator.resetError())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreensLogin)
Have some problem don't using the tag ?
You are using controlled component.
remove onclick from the button
<button type="button" className="button button2 " onClick={() => this.login()}>logar</button>
to
<button type="button" className="button button2">logar</button>
and in your form
<form onSubmit={this.login}>
this way you are actually submitting the form,
on other side you can pass event in button like this
<button type="button" className="button button2 " onClick={(e) => this.login(e)}>logar</button>
and in login function
login = (e) => {
e.preventDefault();
const {email, passwd} = this.state.form
this.props.login(email, passwd)
}
This way you can tell the form that I have handled submission of the form you do not need to do anything.
This question already has an answer here:
Update state values with props change in reactjs
(1 answer)
Closed 4 years ago.
I have a main component, and when I pass down a prop to another component, it doesn't update the style. The display is still none, whereas it's meant to update to block since I have changed the prop to true. What might be wrong?
class Apps extends Component {
constructor(props) {
super(props);
// Don't do this!
this.state = { showing: true, Login: false, Signup: false, Members: false };
}
render() {
return (
<div>
<div
className="container"
style={{ display: this.state.showing ? "block" : "none" }}
>
<div>A Single Page web application made with react</div>
</div>
<LoginComponent view={this.state.Login} />
<div className="buttons">
<a href="" ref="login" onClick={this.Login_onclick.bind(this)}>
{this.state.Login ? "back" : "Login"}
</a>
<br />
</div>
</div>
);
}
Login_onclick(e) {
this.setState({ Login: !this.state.Login });
e.preventDefault(); //alert(e.target.value);
this.setState({ showing: !this.state.showing });
// this.setState({ref: !ref});
}
}
Login Component
class LoginComponent extends Component {
constructor(props) {
super(props);
this.state = {
show: this.props.view
};
}
render() {
return (
<div
className="login"
style={{ display: this.state.show ? "block" : "none" }}
>
<h3>Login</h3>
<br />
Username: <input type="text" ref="username" />
<br />
Password <input type="password" ref="password" />
<button value="Login">Login</button>
</div>
);
}
}
You are setting this.state = { show: this.props.view }; when the component is created. Changing the view prop after that will have no effect.
There is no need for you to set show in your state if your want it to update when the prop updates.
class LoginComponent extends Component {
render() {
return (
<div className="login" style={{ display: (this.props.view ? 'block' : 'none') }}>
<h3>Login</h3><br/>
Username: <input type="text" ref="username"/><br/>
Password <input type="password" ref="password"/>
<button value="Login" >Login</button>
</div>
);
}
}
I am trying to generate a random user information when pressing the button, and display the information above the button. In ProfilePanel.js, I created a avatar and user constants, which will use to show the information. In index.js, the avatar constant works for that since it doesn't need to use the Button. however, for user constant, it doesn't work. In below's code, I am fetching a api data to display user name, but it didn't show anything, I am not sure where wrong, is something wrong in Button.js or index.js. and how can I fix it. Can somebody help me out? Thanks.
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
index.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Panel from "./ProfilePanel";
import axios from 'axios';
import './index.css';
import Button from './Button';
const url = 'https://randomuser.me/api/';
class App extends Component {
constructor(props) {
super(props);
this.state = {
contacts: []
}
}
componentDidMount() {
this.fetchdata();
}
fetchdata() {
axios.get(url)
.then(res => {
console.log(res);
this.setState({ contacts: res.data.results});
});
}
render(){
const {contacts} = this.state;
return (
<div className="panel">
{contacts.map(contact => (
<div class="panel">
<Panel
key={contact.picture} avatar={contact.picture.medium}
/>
<li class="flex-container">
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
<Button title="location" onClick={this.fetchdata}>
</Button>
<Button key={contact.email} title="email">
</Button>
<Button key={contact.phone} title="phone">
</Button>
<Button key={contact.login.password} title="password">
</Button>
</li>
</div>
))}
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
ProfilePanel.js
import React, { Component } from "react";
import PropTypes from "prop-types";
import './index.css';
import Button from './Button';
const style={
borderRadius: 150,
margin: 15,
}
class Panel extends Component {
render() {
const { avatar, user } = this.props;
return (
<div className="Panel">
<div class="panels">
<div className="avatar">
<img src={avatar} class="imageStyle" alt="" width={"200%"} height={"auto"}/>
</div>
</div>
<div class="center">
<h2 className="user">{user}</h2>
</div>
</div>
);
}
}
export default Panel;
Button.js
import './index.css';
import React, { Component } from 'react';
class Button extends Component {
constructor(props) {
super(props);
this.state = {
open:false,
};
}
render() {
const { title } = this.props;
const {open} = this.state;
return (
<button className={` ${open ? 'open' : ''}`}
class='button' onClick={(e) => this.handleClick(e)}>
<div className="panel-heading">
<h2 class='buttoncenter'>{title}</h2>
</div>
</button>
);
}
handleClick(e) {
e.preventDefault();
this.setState({
open: this.state.open
})
}
}
export default Button;
You're not changing state in the handle click. You need to set open to true;
handleClick(e) {
e.preventDefault();
this.setState({
open: true
})
}
You need to pass your user information in index.js. I think you have missed to pass the user props to the panel component, so that it shows the avatar alone. Without passing the users props, you are trying to destructure there in panel component.
//index.js should be like this
render(){
const {contacts} = this.state;
return (
<div className="panel">
{contacts.map(contact => (
<div class="panel">
<Panel
key={contact.picture} user={contact.name} avatar={contact.picture.medium}
/>
<li class="flex-container">
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
<Button title="location" onClick={this.fetchdata}>
</Button>
<Button key={contact.email} title="email">
</Button>
<Button key={contact.phone} title="phone">
</Button>
<Button key={contact.login.password} title="password">
</Button>
</li>
</div>
))}
</div>
);
}