如何正确设置对 React 组件的引用?
How to properly set references to React components?
将 React 与 react-redux
结合使用,我正在尝试获取此登录表单:
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;
其中,同时它被用作:
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;
所以 运行 我得到一个:
Uncaught Invariant Violation: Stateless function components cannot have refs.
所以我有一些问题,我该如何解决这个错误?是什么让我能够像这样导出组件而不是使用 React.createClass
导出组件(我从几个 react/redux 示例中复制了这个模式)是什么魔力?
这些组件是使用 React 提供的无状态函数组件语法定义的。来自 React 文档:
This simplified component API is intended for components that are pure functions of their props. These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate. However, you may still specify .propTypes and .defaultProps by setting them as properties on the function, just as you would set them on an ES6 class.
您 运行 遇到的问题描述如下:
NOTE:
Because stateless functions don't have a backing instance, you can't attach a ref to a stateless function component. Normally this isn't an issue, since stateless functions do not provide an imperative API. Without an imperative API, there isn't much you could do with an instance anyway. However, if a user wants to find the DOM node of a stateless function component, they must wrap the component in a stateful component (eg. ES6 class component) and attach the ref to the stateful wrapper component.
如果您需要此参考,请将您的 LoginButton
组件更改为使用标准 class LoginButton extends React.Component
组件声明语法,或者将您的无状态功能组件包装在有状态组件中。
阅读更多here。
tl;博士
您正在使用 Stateless Component,ref
属性 无法与此类组件一起使用。
长答案
Stateless components可以看作是"static html",它们只有props
作为函数的第一个参数。
他们不能有 state
、refs
或 生命周期方法。
您需要创建一个 React.Component
才能使用 ref
属性。您可以通过两种方式创建此组件:
如果你不使用 ES6 或者你需要使用 mixins
属性 你应该这样做:
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>
);
}
});
如果你使用的是 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>
);
}
}
在无状态组件中你可以使用这样的方法:
const TextFieldSubmit = (props) => {
let input;
return (
<div className='ui input'>
<input
ref={node => input = node}
type='text'
>
</input>
<button
onClick={() => {
props.onSubmit(input.value);
input.value = '';
}}
className='ui primary button'
type='submit'
>
Submit
</button>
</div>
);
};
更多详情请前往:https://www.fullstackreact.com/p/using-presentational-and-container-components-with-redux/
将 React 与 react-redux
结合使用,我正在尝试获取此登录表单:
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;
其中,同时它被用作:
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;
所以 运行 我得到一个:
Uncaught Invariant Violation: Stateless function components cannot have refs.
所以我有一些问题,我该如何解决这个错误?是什么让我能够像这样导出组件而不是使用 React.createClass
导出组件(我从几个 react/redux 示例中复制了这个模式)是什么魔力?
这些组件是使用 React 提供的无状态函数组件语法定义的。来自 React 文档:
This simplified component API is intended for components that are pure functions of their props. These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate. However, you may still specify .propTypes and .defaultProps by setting them as properties on the function, just as you would set them on an ES6 class.
您 运行 遇到的问题描述如下:
NOTE: Because stateless functions don't have a backing instance, you can't attach a ref to a stateless function component. Normally this isn't an issue, since stateless functions do not provide an imperative API. Without an imperative API, there isn't much you could do with an instance anyway. However, if a user wants to find the DOM node of a stateless function component, they must wrap the component in a stateful component (eg. ES6 class component) and attach the ref to the stateful wrapper component.
如果您需要此参考,请将您的 LoginButton
组件更改为使用标准 class LoginButton extends React.Component
组件声明语法,或者将您的无状态功能组件包装在有状态组件中。
阅读更多here。
tl;博士
您正在使用 Stateless Component,ref
属性 无法与此类组件一起使用。
长答案
Stateless components可以看作是"static html",它们只有props
作为函数的第一个参数。
他们不能有 state
、refs
或 生命周期方法。
您需要创建一个 React.Component
才能使用 ref
属性。您可以通过两种方式创建此组件:
mixins
属性 你应该这样做:
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>
);
}
});
如果你使用的是 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>
);
}
}
在无状态组件中你可以使用这样的方法:
const TextFieldSubmit = (props) => {
let input;
return (
<div className='ui input'>
<input
ref={node => input = node}
type='text'
>
</input>
<button
onClick={() => {
props.onSubmit(input.value);
input.value = '';
}}
className='ui primary button'
type='submit'
>
Submit
</button>
</div>
);
};
更多详情请前往:https://www.fullstackreact.com/p/using-presentational-and-container-components-with-redux/