Reputation: 2183
I've just started trying out react after a few tutorials on Redux and React and I'm getting an error in the console:
Warning: Stateless function components cannot be given refs (See ref "username" in FieldGroup created by Login). Attempts to access this ref will fail.
What is the proper way to pass form field input values to my submit button? Should these values go into the redux store? After reading the docs: https://reactjs.org/docs/refs-and-the-dom.html#a-complete-example it seems like I should avoid refs in this case. So, without refs how do I get the input values to the submit button? Thanks for any help.
Login.jsx
import React, {Component, PropTypes} from 'react';
import {Row, Col, FormControl, FormGroup, ControlLabel, HelpBlock, Checkbox, Button} from 'react-bootstrap';
export default class Login extends Component {
render() {
const { errorMessage } = this.props;
function FieldGroup({ id, label, help, ...props }) {
return (
<FormGroup controlId={id}>
<ControlLabel>{label}</ControlLabel>
<FormControl {...props} />
{help && <HelpBlock>{help}</HelpBlock>}
</FormGroup>
);
}
const formInstance = (
<Col xs={12} md={8} mdOffset={2}>
<code><{'Col xs={12} md={8}'} /></code>
<form>
<FieldGroup
id="formControlsEmail"
type="email"
label="Email address"
placeholder="Enter email"
ref="username"
/>
<FieldGroup
id="formControlsPassword"
label="Password"
type="password"
ref="password"
/>
<Checkbox checked readOnly>
Checkbox
</Checkbox>
<Button type="submit" onClick={(event) => this.handleClick(event)}>
Submit
</Button>
{errorMessage &&
<p>{errorMessage}</p>
}
</form>
</Col>
);
return formInstance;
}
handleClick(event) {
const username = this.refs.username
const password = this.refs.password
const creds = { username: username.value.trim(), password: password.value.trim() }
this.props.onLoginClick(creds)
}
}
Login.propTypes = {
onLoginClick: PropTypes.func.isRequired,
errorMessage: PropTypes.string
}
Upvotes: 1
Views: 728
Reputation: 2013
Functional components in react (stateless) don't have refs.
From the official docs
Refs and Functional Components You may not use the ref attribute on functional components because they don’t have instances:
Use an ES6 class instead if you need refs, if not use this.state
from your Parent Login
component with class syntax and use that instead with this.setState(yourState)
when the input value changes on your FieldGroup
And then in your you would do
handleClick(event) {
const username = this.state.username
const password = this.state.password
const creds = { username: username.value.trim(), password: password.value.trim() }
this.props.onLoginClick(creds)
}
From the docs :
You can, however, use the ref attribute inside a functional component as long as you refer to a DOM element or a class component:
Upvotes: 1