React.js: conditional rendering does not load child component - reactjs

I need to render the child component during conditional rendering. It is not displayed in the current version.
If you insert into the html markup, then there are no errors, the component is rendered normally.
What could be my mistake with conditional rendering?
Parent component:
export default class App extends Component {
data = {
email: "a#b.net",
password: "adc"
}
state = {
email: "",
password: ""
}
emailChange=(e)=>{
this.setState({email: e.target.value});
}
passwordChange=(e)=>{
this.setState({password: e.target.value});
}
buttonSubmit=(e)=>{
let p=this.state.email===this.data.email
&& this.state.password===this.data.password ? <div><Page1/></div> : alert('poi');
e.preventDefault()
}
render() {
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<form noValidate autoComplete="off"
onSubmit={this.buttonSubmit}>
<div style={{marginTop:"150px"}}>
<Grid container spacing={2}>
<Grid item xs={12} >
<TextField
id="outlined-name"
label="e-mail"
variant="outlined"
value={this.state.email}
onChange={this.emailChange}/>
</Grid>
<Grid item xs={12} >
<TextField
className="MuiInput-input"
id="outlined-name"
label="password"
variant="outlined"
value={this.state.password}
onChange={this.passwordChange}/>
</Grid>
<Grid item xs={12}>
<Button
style={{width:'210px'}}
type="submit"
fullWidth
variant="contained"
color="primary"
>
Enter
</Button>
</Grid>
</Grid>
</div>
</form>
</Container>
);
}
}
Child component that is not rendered during conditional rendering:
const Page1 =()=>{
return (
<div style={{height: "100vh"}}>
<Header/>
<Grid container spacing={3}>
<Grid item xs={3}>
<Paper><ButtonPage/></Paper>
</Grid>
<Grid item xs={12}>
<Paper><ButtonWindow /></Paper>
</Grid>
</Grid>
</div>
);
}

You're just assigning your child component conditionally to a local variable p, that you never render. I'd change your logic like this:
buttonSubmit=(e)=>{
let p=(this.state.email===this.data.email &&
this.state.password===this.data.password) ?
<div><Page1/></div>
:
null;
this.setState({p: p});
e.preventDefault()
}
render() {
...
{this.state.p}
}

Related

React Material UI Button onclick not working (The 3rd parameter is expected to be the HTML form element or the style selector of form )

I have a problem about clicking Button provided by Material UI to send information as an email.
When I click the button, I got this kind of error message shown below.
The 3rd parameter is expected to be the HTML form element or the style selector of form
How can I fix it?
Here are my code snippets shown below.
Contact Component
const handleSubmit = (e) => {
e.preventDefault();
... The usage of EMAILJS
}
<Grid item xs={12} className="p_30">
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField fullWidth name="name" label="Name" onChange={handleName}/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField fullWidth name="email" label="E-mail" onChange={handleEmail}/>
</Grid>
<Grid item xs={12}>
<TextField fullWidth name="message" label="Message" multiline minRows={4} onChange={handleMessage}/>
</Grid>
<Grid item xs={12}>
<CustomButton text={"Submit"} submitfunction={(e) => handleSubmit(e)}/>
</Grid>
</Grid>
</Grid>
CustomButton Component
import { Button } from "#material-ui/core";
const CustomButton = ({ text, icon, submitfunction }) => {
return (
<Button
className="site_btn"
onClick={submitfunction}
endIcon={
icon ? (
<div className="icon_container">
{icon}
</div>
) : null
}
>
<span className="button_text">{text}</span>
</Button>
);
};
export default CustomButton;

React : Unable to set the values in the form

I want to set the values of the form if the edit is true. I am passing the editable state to true and passing the first element of the array but when the component is mounted it didn't show the 0th element values that were sent from the parent component to the child component.
Here's the code :
Milestone.js
import React, { Component } from 'react';
import "./milestone.css";
import MileStoneForm from './mileStoneForm'
import {LEFT_ARROW, ROUTES_PATH } from "../../constants";
export default class MilestoneComp extends Component {
constructor(props) {
super(props);
this.state = {
arr: [],
edit:true
}
}
backPage = () => {
this.props.history.push(ROUTES_PATH.CREATE_PROJECT)
}
handleData=(data)=>{
const {arr}=this.state
arr.push(data)
//localStorage.setItem('mileStoneData',JSON.stringify(arr))
console.log(arr)
}
render() {
return (
<div style={{ background: "#F3F3F3", minHeight: "100vh" }}>
<div className="header-div">
<img
src={LEFT_ARROW}
alt="back"
style={{ cursor: "pointer" }}
className="left-arrow-size left-back-btn-bt-mar"
onClick={this.backPage}
/>
</div>
<MileStoneForm arr={this.state.arr[0]} handleData={this.handleData} edit={this.state.edit}/>
</div>
)
}
}
MileStoneForm.js
import { InputBase,Grid,TextareaAutosize} from '#material-ui/core'
import React, { Component } from 'react'
import { DROP_D } from "../../constants";
import { PRIVATE_SwITCH,PUBLIC_SwITCH } from "../../constants";
import NormalButton from '../../common/component/normalButton';
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css';
class MileStoneForm extends Component {
constructor(props){
super(props)
this.state={
deliverable_name:"",
due_date:"",
deliverable_notes:"",
milestone_based_payment:false,
deliverable_name_error:"",
due_date_error:"",
deliverable_notes_error:"",
percent_rate:0,
percent_rate_error:""
}
}
componentDidMount(){
console.log('component did mount')
if(this.props.edit===true){
console.log('editable')
if(this.props.arr){
console.log('array')
this.setState({
deliverable_name:this.props.arr.milestoneName,
deliverable_notes:this.props.arr.description,
due_date:this.props.arr.dueDate,
milestone_based_payment:this.props.arr.isMilestoneBasedPayment,
percent_rate:this.props.arr.percentageRate
},()=>{
console.log('edit')
})
}
}
}
render() {
const {deliverable_name,deliverable_name_error,deliverable_notes,deliverable_notes_error,
due_date,due_date_error,milestone_based_payment,}=this.state
return (
<>
<div className="milestone">
<div className="milestone-header">ADD MILESTONE</div>
<Grid container className="milestone-deliverable-name-date">
<Grid item md={6} lg={6} xs={12}>
<div className="milestone-deliverable-name">DELIVERABLE NAME</div>
<InputBase
className={`milestone-input-deliverable-name`}
autoComplete={"off"}
placeholder={"MileStone Name"}
onChange={e=>this.handleChange(e,'deliverable_name')}
value={deliverable_name}
maxLength="100"
autoFocus={true}/>
{deliverable_name_error && (
<div className="input-error-style">{deliverable_name_error}</div>
)}
</Grid>
<Grid item md={6} lg={6} xs={12}>
<div className="milestone-due-date">
DUE DATE
</div>
<label>
<DatePicker
dateFormat="MM/dd/yyyy"
margin="normal"
selected={due_date}
placeholderText="Due Date"
onChange={date=>this.handleChangeDate(date,'due_date')}
maxDate={new Date()}
className={`milestone-input-due-date`}
/>
<img src={DROP_D} alt="drop down" style={{cursor:'pointer'}} className='dropdown-milestone'/>
</label>
{due_date_error && (
<div className="input-error-style">{due_date_error}</div>
)}
</Grid>
<Grid item md={12} lg={12} xs={12}>
<div className="milestone-notes-description">
<div className="milestone-deliverable-notes">DELIVERABLE NOTES</div>
<div className="milestone-description-notes">Add description below</div>
<TextareaAutosize className={`milestone-textarea-description`}
onChange={(e)=>this.handleChange(e,'deliverable_notes')}
value={deliverable_notes}/>
{deliverable_notes_error && (
<div className="input-error-style">{deliverable_notes_error}</div>
)}
</div>
</Grid>
<Grid item md={12} lg={12} xs={12}>
<div className="milestone-payment">MILESTONE BASED PAYMENT?</div>
{this.togglePayment()}
</Grid>
<Grid item md={12} lg={12} xs={12}>
{milestone_based_payment ?<>
<div className="percent-rate">PERCENT RATE</div>
<InputBase
className={`milestone-percent-rate`}
autoComplete={"off"}
placeholder={"20%"}
maxLength="100"
value={this.state.percent_rate}
onChange={(e)=>{this.handleChange(e, "percent_rate")}}
/>
{
this.state.percent_rate_error && (
<div className="input-error-style">{this.state.percent_rate_error}</div>
)
}
</> :''}
</Grid>
<Grid item xs={12} sm={12} md={4} lg={4}></Grid>
<Grid item xs={12} sm={12} md={4} lg={4}></Grid>
<Grid item xs={12} sm={12} md={4} lg={4}>
<div className={milestone_based_payment?"milestone-button":"milestone-button-margin-btm"}>
<NormalButton
buttonValue="ADD"
className="btn-create-project flex-justify"
icon_color="black"
handleButtonAction={()=>this.handleSubmit()}
/>
</div>
</Grid>
</Grid>
</div>
</>
)
}
}
export default MileStoneForm
You are mutating your state with push, never do that. You have to create a new state object.
handleData=(data)=>{
const { arr }= this.state
const nextArr= {...arr, data}
//localStorage.setItem('mileStoneData',JSON.stringify(arr))
this.setState({arr: nextArr});
console.log(arr)
}
The console.log will show the new data anyway, since you are changing that object, but since the object reference will be the same (same object as before), it will not rerender.

React : How can I set the error messages?

I am trying to set the error message but as in the state I've passed initial Values object, I'm unable to set the state. How can I achieve this in react? How can I set the error messages in the set State function? Can someone help me?. After console logging it is showing the error in the console. But how can I show this on screen? Thanks in advance.
Here's the code :
const initialValues={
deliverable_name:"",
due_date:new Date(),
deliverable_notes:"",
milestone_based_payment:false,
deliverable_name_error:"",
due_date_error:"",
deliverable_notes_error:""
}
class MileStoneForm extends Component {
constructor(props){
super(props)
this.state={
initialValues
}
}
handleChange=(e,type)=>{
let error=true
if(type==='deliverable_notes'){
if(e.target.value.length>300){
error=false
this.setState({deliverable_notes_error:'Description must contain less than 300 characters'})
}
}
if(error){
this.setState({
[type]:e.target.value,
[type+"_error"]: ""
})
}
}
validateMileStoneName=()=>{
if(!this.state.initialValues.deliverable_name || this.state.initialValues.deliverable_name.length< 4 ){
console.log("enter deliverable name")
this.setState({deliverable_name_error:'Please enter deliverable name'})
}
}
validateMileStoneDueDate=()=>{
if(!this.state.initialValues.due_date){
this.setState({due_date_error:'Please enter due date'})
}
}
validateMileStoneDescription=()=>{
if(!this.state.initialValues.deliverable_notes){
this.setState({deliverable_notes_error:'Please enter description'})
}
}
handleSubmit=(data)=>{
this.validateMileStoneName()
this.validateMileStoneDescription()
console.log(data)
this.props.handleData(data)
}
render() {
const {initialValues}=this.state
return (
<>
<div className="milestone">
<div className="milestone-header">ADD MILESTONE</div>
<Grid container className="milestone-deliverable-name-date">
<Grid item md={6} lg={6} xs={12}>
<div className="milestone-deliverable-name">DELIVERABLE NAME</div>
<div>
<InputBase
className={`milestone-input-deliverable-name`}
autoComplete={"off"}
placeholder={"MileStone Name"}
onChange={e=>this.handleChange(e,'initialValues.deliverable_name')}
value={initialValues.deliverable_name}
maxLength="100"
autoFocus={true}/>
{initialValues.deliverable_name_error && (
<div className="input-error-style">{initialValues.deliverable_name_error}</div>
)}
</div>
</Grid>
<Grid item md={6} lg={6} xs={12}>
<div>
<div className="milestone-due-date">
DUE DATE
</div>
<InputBase
className={`create-project-due-date`}
autoComplete={"off"}
type="date"
placeholder={"DUE DATE"}
onChange={e=>this.handleChange(e,'due_date')}
value={initialValues.due_date}/>
{initialValues.due_date_error && (
<div className="input-error-style">{initialValues.due_date_error}</div>
)}
</div>
</Grid>
</Grid>
<Grid container className="milestone-deliverable-notes">
<Grid item md={12} lg={12} xs={12}>
<div className="milestone-notes-description">
<div className="milestone-deliverable-notes">DELIVERABLE NOTES</div>
<div className="milestone-description-notes">Add description below</div>
<TextareaAutosize className={`milestone-textarea-description`}
onChange={(e)=>this.handleChange(e,'deliverable_notes')}
value={initialValues.deliverable_notes}/>
{initialValues.deliverable_notes_error && (
<div className="input-error-style">{initialValues.deliverable_notes_error}</div>
)}
</div>
</Grid>
</Grid>
<div className={initialValues.milestone_based_payment?"milestone-button":"milestone-button-margin-high"}>
<Grid container spacing={10}>
<Grid item xs={12} sm={12} md={4} lg={4}></Grid>
<Grid item xs={12} sm={12} md={4} lg={4}></Grid>
<Grid item xs={12} sm={12} md={4} lg={4}>
<div className="milestone-button-margin-btm">
<NormalButton
buttonValue="ADD"
className="btn-create-project flex-justify"
icon_color="black"
handleButtonAction={()=>this.handleSubmit(initialValues)}
/>
</div>
</Grid>
</Grid>
</div>
</div>
</>
)
}
}
export default MileStoneForm
You're mixing initialValue in the state which is an object, with the properties you're setting. So after an error, your state is actually looking like this:
this.state = {
initialValue: [object] // this could potentially mutate (a bug).
deliverable_notes_error: "Please set ....",
}
What you need to do is use the spread syntax to set your initial state:
constructor(props) {
this.state = {
...initialValues // your state is now a soft clone of the object
};
}
render(props) {
const { deliverable_notes_error } = this.state;
return (
{ deliverable_notes_error && <div>{ deliverable_notes_error }</div> }
);
}
3 things
I would move the error messages inside State.
deliverable_name_error:"",
due_date_error:"",
deliverable_notes_error:""
Update this.setState - already done
Display error messages - also doing.
Basically, if you move everything from initialValues into state, your code should work.

React Router V4 <Redirect> Doesn't Trigger on Form Submission

I have a route component that redirects in its render() based on whether or a submit form in the component’s modal has been switched to true.
Home.JS
import { BrowserRouter as Router, Route, Link, Redirect } from "react-router-dom";
class Home extends Component {
constructor(props) {
super(props)
this.state = {
dialogueOpen: false,
loginMessage: '',
name: '',
password: '',
newUsername: '',
newPassword: '',
returnedUser: undefined,
registrationMessage: '',
redirectToSignupSuccess: false
}
this.checkUniqueUsername = this.checkUniqueUsername.bind(this)
this.handleChange = this.handleChange.bind(this)
this.handleLogin = this.handleLogin.bind(this)
this.handleOpen = this.handleOpen.bind(this)
this.handleRegistration = this.handleRegistration.bind(this)
}
This is the method to switch redirectToSignupSuccess to true.
handleRegistration = event => {
//check that username and passwords aren't empty strings
if (this.state.newUsername.length() > 0 && this.state.newPassword.length() > 0) {
//check that the new username isn't already in the database
this.checkUniqueUsername(this.state.newUsername)
.then(isUnique => {
console.log(isUnique)
if (isUnique === true) {
//console.log("the username is unique")
axios.post('http://localhost:4242/createuser', {
username: this.state.newUsername,
password: this.state.newPassword
})
.then( (response) => {
console.log(response)
this.setState({redirectToSignupSuccess: true}, () => {
console.log(this.state.redirectToSignupSuccess)
})
//this.handleClose()
})
.catch((error) => {
console.log(error);
});
}
})
}
else {
this.setState({registrationMessage:
"Sorry, but we need a username and password for you to sign up"})
}
event.preventDefault();
}
The render()
render() {
let isAuthed = localStorage.getItem("authorized");
let redirectToSignupSuccess = this.state.redirectToSignupSuccess
if (isAuthed === "true") {
return (<Redirect to='/inner' />)
}
if (redirectToSignupSuccess === true) {
return (<Redirect to='/signupsuccess' />)
}
return (
<div>
<h1 className="green home-logo">APPLi</h1>
<div className="login-message">
<h4>{this.state.loginMessage}</h4>
</div>
<form onSubmit={this.handleLogin} style={{ padding: 8 }}>
<Grid container spacing={16} direction="row" justify="center">
<Grid item xs={2} >
<FormControl margin="normal">
<InputLabel htmlFor="component-simple">Name</InputLabel>
<Input id="component-simple" value={this.state.name} onChange={this.handleChange('name')} />
</FormControl>
</Grid>
<Grid item xs={2} >
<FormControl margin="normal">
<InputLabel htmlFor="component-simple">Password</InputLabel>
<Input id="component-simple" value={this.state.password} onChange={this.handleChange('password')} />
</FormControl>
</Grid>
<Grid item xs={12}>
<Button color="secondary" label="submit" type="Submit" variant="contained" >Log In</Button>
</Grid>
</Grid>
</form>
<Button onClick={this.handleOpen} color="primary" variant="contained">Sign Up</Button>
<Dialog open={this.state.dialogueOpen} onClose={this.handleClose}>
<h2>Register for an account</h2>
<form onSubmit={this.handleRegistration} style={{ padding: 8 }}>
<Grid container spacing={16} justify="center">
<Grid item xs={6} >
<FormControl required={true}>
<InputLabel htmlFor="component-simple">Your Username</InputLabel>
<Input id="component-simple" value={this.state.newUsername} onChange={this.handleChange('newUsername')}/>
</FormControl>
</Grid>
<Grid item xs={6} >
<FormControl required={true}>
<InputLabel htmlFor="component-simple">Your Password</InputLabel>
<Input id="component-simple" value={this.state.newPassword} onChange={this.handleChange('newPassword')} />
</FormControl>
</Grid>
<Grid item xs={12}>
<p>{this.state.registrationMessage}</p>
<Button color="secondary" label="submit" type="Submit" variant="contained">Create Account</Button>
</Grid>
</Grid>
</form>
</Dialog>
</div>)
Routes in App.js
render() {
return (
<Router>
<div className="App">
<div className="portfolioBar">
<div className="arrowContainer">
<FontAwesomeIcon icon="arrow-left" color="black" size="3x" />
</div>
</div>
<Route exact path="/" render={(props) =>
<Home authorizeUser={this.authorizeUser} setCurrentUser={this.setCurrentUser} currentUser={this.state.currentUser} {...props} />
}/>
<Route path="/signupsuccess" component={SignupSuccess} />
<Route exact path="/inner" render={(props) =>
<UserView currentUser={this.state.currentUser} currentUserId={this.state.currentUserId} handleLogout={this.handleLogout} {...props} />
}/>
</div>
</Router>
);
}
}
export default App;
Normally, when the page’s form is submitted, the api should send the new user information to the database, and they should redirect to /signupsuccess. Instead, what happens is that the page refreshes, and the api call to the database isn’t made. I’ve set the event.preventDefault() on the form, but instead the console flashes a turn of error messages, and the page resets. What could I be missing?

Using Ref inside stateless functional component is not working in React JS

I am developing a React JS Web Application. I am new to react js. Now, I am trying to use Ref inside the stateless functional component to retrieve the input value. I followed some of the solutions I found online.
This is my component
const Login = (props) => {
const {
classes,
width
} = props;
// Flip container to column on mobile screens.
const panelDirection = width === 'xs' ? 'column' : 'row';
let emailInput = null;
let passwordInput = null;
return (
<Grid
container
direction="row"
spacing={0}
justify="center"
alignItems="center"
className={classes.background}
>
<Grid item sm={10} xs={12} className={scss.panel}>
<form className="full-height" action="post">
<Grid direction={panelDirection} container spacing={0}>
<Grid
item
sm={6}
xs={12}
>
<Card className={classNames(scss.card, classes['primary-card'])}>
<CardContent className={scss['signup-content']}>
<img src={logoImage} className={scss['signup-logo']} alt="logo" />
<Typography variant="headline" component="h2" gutterBottom>
Web Portal
</Typography>
</CardContent>
<CardActions>
<Button fullWidth href="/register" color="secondary" variant="raised">Create an account</Button>
</CardActions>
</Card>
</Grid>
<Grid
item
sm={6}
xs={12}
>
<Card className={scss.card}>
<CardContent>
<TextField
ref={(input) => { emailInput = input }}
label="Email Address"
fullWidth
/>
<TextField
ref={(input) => { passwordInput = input }}
label="Password"
fullWidth
margin="normal"
type="password"
/>
</CardContent>
<CardActions className={scss['login-actions']}>
<Button href="/login" color="primary" variant="raised">Login</Button>
<Button href="/forgot-password">Forgot Password</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</form>
</Grid>
</Grid>
);
};
As you can see, I am using ref to retrieve the values of email and password input fields. But, when I run, it is still giving me this error.
Warning: Stateless function components cannot be given refs. Attempts to access this ref will fail.
So, how can I fix my code? How can I use Ref correctly in the stateless function component?
Obviously, I followed this, How can I attach to a stateless component's ref in React?
I tried using the class as well. It is giving me the same error. This is the class version of my component.
class Login extends React.Component {
submitForm = e => {
e.preventDefault();
}
constructor(props)
{
super(props);
this.emailInput = React.createRef();
this.passwordInput = React.createRef();
}
render () {
const { classes, width } = this.props;
// Flip container to column on mobile screens.
const panelDirection = width === 'xs' ? 'column' : 'row';
return (
<Grid
container
direction="row"
spacing={0}
justify="center"
alignItems="center"
className={classes.background}
>
<Grid item sm={10} xs={12} className={scss.panel}>
<form className="full-height" action="post" onSubmit={this.submitForm}>
<Grid direction={panelDirection} container spacing={0}>
<Grid
item
sm={6}
xs={12}
>
<Card className={classNames(scss.card, classes['primary-card'])}>
<CardContent className={scss['signup-content']}>
<img src={logoImage} className={scss['signup-logo']} alt="logo" />
<Typography variant="headline" component="h2" gutterBottom>
Web Portal
</Typography>
</CardContent>
<CardActions>
<Button fullWidth href="/register" color="secondary" variant="raised">Create an account</Button>
</CardActions>
</Card>
</Grid>
<Grid
item
sm={6}
xs={12}
>
<Card className={scss.card}>
<CardContent>
<TextField
ref={this.emailInput}
label="Email Address"
fullWidth
/>
<TextField
ref={this.passwordInput}
label="Password"
fullWidth
margin="normal"
type="password"
/>
</CardContent>
<CardActions className={scss['login-actions']}>
<Button type="submit" color="primary" variant="raised">Login</Button>
<Button href="/forgot-password">Forgot Password</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</form>
</Grid>
</Grid>
)
}
}
Login.propTypes = {
classes: PropTypes.shape({}).isRequired,
width: PropTypes.string.isRequired
};
export default compose(withWidth(), withStyles(themeStyles, { withTheme: true }))(Login);
If you insist in using stateless component (which to me they are great) you should use a callback to retrieve the value of your input:
// Login.js
const Login = (props) => {
const {
classes,
width,
onChange, // <- get the callback here
} = props;
...
return (
...
<TextField
name="email"
onChange={onChange}
label="Email Address"
fullWidth
/>
<TextField
name="password"
onChange={onChange}
label="Password"
fullWidth
margin="normal"
type="password"
/>
...
);
// Somewhere to include Login
class LoginPage extends Component {
...
handleInputChange({ target }) {
...
console.log(target.name, target.value);
}
render (
<Login onChange={this.handleInputChange} ... />
)
}
// Or connect it to Redux
const mapDispatchToProps = dispatch => {
const updateLoginInputValues = ({ target }) => dispatch(updateLoginInputValues(target.name, target.value)));
return {
onChange: updateLoginInputValues,
}
};
const connectedLogin = connect(null, mapDispatchToProps)(Login
The only part that you can improve is basically either handling the values by a state management or directly with React. Other than this you need to address the state at some point and you can't keep all of you components stateless.
State less component means it does not contains state, component only updates through props. So you can use class container for that. here is the solution...
import React, { Component } from "react";
class Login extends Component {
constructor(props) {
super(props);
this.emailInput = React.createRef();
this.passwordInput = React.createRef();
}
render() {
const { classes, width } = this.props;
// Flip container to column on mobile screens.
const panelDirection = width === "xs" ? "column" : "row";
return (
<Grid container direction="row" spacing={0} justify="center" alignItems="center" className={classes.background}>
<Grid item sm={10} xs={12} className={scss.panel}>
<form className="full-height" action="post">
<Grid direction={panelDirection} container spacing={0}>
<Grid item sm={6} xs={12}>
<Card className={classNames(scss.card, classes["primary-card"])}>
<CardContent className={scss["signup-content"]}>
<img src={logoImage} className={scss["signup-logo"]} alt="logo" />
<Typography variant="headline" component="h2" gutterBottom>
Web Portal
</Typography>
</CardContent>
<CardActions>
<Button fullWidth href="/register" color="secondary" variant="raised">
Create an account
</Button>
</CardActions>
</Card>
</Grid>
<Grid item sm={6} xs={12}>
<Card className={scss.card}>
<CardContent>
<TextField ref={this.emailInput} label="Email Address" fullWidth />
<TextField ref={this.passwordInput} label="Password" fullWidth margin="normal" type="password" />
</CardContent>
<CardActions className={scss["login-actions"]}>
<Button href="/login" color="primary" variant="raised">
Login
</Button>
<Button href="/forgot-password">Forgot Password</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</form>
</Grid>
</Grid>
)
}
}
export default Login;
Now you can get value of the textfields like this
this.emailInput.current.value and this.passwordInput.current.value

Resources