diegoaguilar diegoaguilar - 3 months ago 19
React JSX Question

How to properly set references to React components?

Using React with

react-redux
, I'm trying to get this login form:

import React from 'react'
import RaisedButton from 'material-ui/lib/raised-button';
import TextField from 'material-ui/lib/text-field';
const LoginButton = () => (
<form>
<div>
<TextField hint="E-mail" floatingLabelText="E-mail" ref="emailInput"></TextField><br/>
</div>
<div>
<TextField hint="Contraseña" floatingLabelText="Contraseña" type="password" ref="passwordInput"></TextField><br/><br/>
</div>
<div>
<RaisedButton label="Acceder" primary={true} onClick={e => {
console.log(emailInput.value);
}}/>
</div>
</form>
);

export default LoginButton;


Which, at the same time it's being used as:

import React from 'react'
import Card from 'material-ui/lib/card/card';
import CardActions from 'material-ui/lib/card/card-actions';
import CardHeader from 'material-ui/lib/card/card-header';
import CardText from 'material-ui/lib/card/card-text';
import CardTitle from 'material-ui/lib/card/card-title';
import RaisedButton from 'material-ui/lib/raised-button';

import Paper from 'material-ui/lib/paper';
import { Link } from 'react-router'
import LoginForm from '../containers/LoginForm'

const divStyle = {
marginTop: '100px'
};

const paperStyle = {
padding: '25px'
}

const Login = () => (
<div className="row center-md" style={divStyle}>
<div className="col-md-6">
<div className="box">
<Paper zDepth={4} style={paperStyle}>
<div>
<h1>Acceder</h1>
</div>
<LoginForm />
</Paper>
</div>
</div>
</div>
);

export default Login;


So running this I'm getting a:

Uncaught Invariant Violation: Stateless function components cannot have refs.


So I have some questions, how should I fix this error? What's the magic allowing me to export components like this instead of exporting with
React.createClass
(I've copied this pattern from a couple of react/redux examples)?

Answer

tl;dr

You are using a Stateless Component, the ref property can't be used with this type of component.

Long answer

Stateless components can be seen as "static html", they only have the props given to it as the first argument of the function.

They can't have state, refs or lifecycle methods.

You need to create a React.Component to be able to use the ref property. You can create this component in two ways:

If you are not using ES6 or you need to use the mixins property you should do:
var React = require("react");

module.exports = React.createClass({
  render() {
    return (
      <form>
        <div>
          <TextField hint="E-mail" floatingLabelText="E-mail" ref="emailInput"></TextField><br/>
        </div>
        <div>
          <TextField hint="Contraseña" floatingLabelText="Contraseña" type="password" ref="passwordInput"></TextField><br/><br/>
        </div>
        <div>
          <RaisedButton label="Acceder" primary={true} onClick={e => {
              console.log(emailInput.value);
            }}/>
        </div>
      </form>
    );
  }
});
and if you are using ES6
import React, { Component } from "react"

export default class Form extends Component {
  render() {
    return (
      <form>
        <div>
          <TextField hint="E-mail" floatingLabelText="E-mail" ref="emailInput"></TextField><br/>
        </div>
        <div>
          <TextField hint="Contraseña" floatingLabelText="Contraseña" type="password" ref="passwordInput"></TextField><br/><br/>
        </div>
        <div>
          <RaisedButton label="Acceder" primary={true} onClick={e => {
              console.log(emailInput.value);
            }}/>
        </div>
      </form>
    );
  }
}