2016-05-17 46 views
9

我不知道我是否正确地做到了这一点...... 如果我想从输入中获取值,我使用this.refs.whatever.value.trim(),但如果该输入是无状态函数组件我确实检索onSubmit的值?React无状态组件this.refs..value?

我知道这是不正确的现在研究后,但你应该如何从这些输入字段中获得价值?

import React, {Component} from 'react' 

import {InputField} from '../components/forms/InputField' 
import {Button} from '../components/forms/Button' 

export default class SignupWrapper extends Component { 
    _handleSubmit(e) { 
    e.preventDefault(); 
    const email = this.refs.email.value.trim(); 
    const password = this.refs.password.value.trim(); 
    const confirm = this.refs.confirm.value.trim(); 
    console.log({email, password, confirm}); 
    } 

    render() { 
    return (
     <form id="application-signup" onSubmit={this._handleSubmit.bind(this)}> 
     <InputField type={'email'} name={'email'} text={'email'} 
        helpBlock={'email is required'} ref="email" /> 
     <InputField type={'password'} name={'password'} text={'password'} 
        helpBlock={'password is required'} ref="password" /> 
     <InputField type={'password'} name={'confirm'} text={'confirm password'} 
        helpBlock={'password confirmation is required'} ref="confirm" /> 
     <Button type={'submit'} className={'btn btn-primary'} text={'signup'} /> 
     </form> 
    ) 
    } 
} 

这是无状态的inputfield

import React from 'react' 

export const InputField = (props) => (
    <div className="form-group col-xs-12"> 
    <label htmlFor={props.name}>{props.text}</label> 
    <input type={props.type} name={props.name} className="form-control" 
      data-stripe={props.stripe} /> 
    <span className="help-block">{props.helpBlock}</span> 
    </div> 
) 
+0

http://stackoverflow.com/questions/25941585/react-refs-with-components – jmancherje

+0

我的建议是:避免裁判,始终。在你的情况下,使你的容器有状态,并将更改处理程序传递给输入字段。无论何时输入字段更改,它都会调用父处理程序来更新状态。 – wintvelt

+0

谢谢,我现在明白了。这是一个条形的表单,将信用卡信息存储在状态是否安全?为什么裁判不好?我想知道,因为我完成了两个教程:官方MDG Meteor + React和LevelUpTuts的Meteor + React for Everyone uses refs。你能帮我解释一下吗? – cocacrave

回答

7

编辑:看起来这是不是问题了,因为关于如何处理这种情况下新的想法出现了,因为这个答案写。 请参阅inanc的答案,而不是这一个。

Refs在无状态组件中不可用。 从React Docs

因为无状态的功能,没有支持的实例,您不能在裁判附加到一个无状态的功能成分。通常情况下这不是问题,因为无状态函数不提供强制性的API。如果没有强制性的API,无论如何你都无法对一个实例做些什么。但是,如果用户想要查找无状态函数组件的DOM节点,则它们必须将组件包装在有状态组件(例如,ES6类组件)中,并将该ref附加到有状态包装组件。

+0

其实你可以从无状态的组件引用一个dom元素。从文档: ** [但是,只要您引用DOM元素或类组件,就可以在功能组件中使用ref属性](https://reactjs.org/docs/refs-and- the-dom.html#exposeing-dom-refs-to-parent-components)** –

31

您可以在无状态组件中使用ref

这里还有我的example fiddle它向你展示了它是如何工作的。

import React from 'react' 

export default ({ onChange }) => { 
    let cityInput 

    const onSubmit = e => { 
    e.preventDefault() 
    onChange(cityInput.value) 
    } 

    return (
    <form onSubmit={ onSubmit }> 
     <input type='text' placeholder='Enter City Name' 
     ref={ el => cityInput = el } /> 
     <button>Go!</button> 
    </form> 
) 
} 
+0

你确定配偶吗? – Muhaimin

+0

@MuhaiminAbdul是的,我敢肯定。看看我的小提琴:https://jsfiddle.net/inancgumus/dvfdj4wx/ –

+0

忘记注意'let' cityInput – Muhaimin

1

@inanc,显示不错的方法,但我提出了另一种使用事件目标来获取DOM元素引用的方法。在使用表单元素时,可以命名输入元素并使用它来访问表单对象。

const onSubmit = fn => e => { 
    e.preventDefault() 
    const city = e.target.city.value // Access elements through `form` 
    if (city) { 
    fn(city) 
    } 
} 

const MyComponent = ({ 
    onChange 
}) => { 
    return ( 
    <div> 
     <form onSubmit={onSubmit(onChange)}> 
     <input type='text' name='city' placeholder='Enter City Name' /> 
     <button>Go!</button> 
     </form> 
    </div> 
) 
} 
1

如今,你想要avoid to use the ref attribute从输入字段获得值。相反,你应该使用React的本地状态。 ref属性仅保留一个few use cases

  • 管理焦点,文本选择,或媒体播放
  • 与第三方DOM库集成
  • 触发势在必行动画
0

你可以用” t在无状态的反应组件中使用ref(+ a给Moti Azu从他的文档中摘录)。

您可以使用多种技术来得到的东西进/出无状态的组件(不使用参考或使用类组件),我创建了下面的代码片段来说明

  1. 您如何传递的东西变成无国籍组件(标签道具在父组件中静态设置)。
  2. 如何从一个无状态的组件得到的东西不使用裁判的(输入组件)

尝试一下&让我知道,如果你仍然有问题,享受...

// Stateless Component (just a <div> component with prop) 
 
const StatelessComponent = props => (
 
    <div>{props.label}</div> 
 
); 
 

 
// Stateless input Component 
 
const InputComponent = props => { 
 
    return (
 
    <input 
 
     value={props.name} 
 
     onChange={props.handleChange} 
 
    /> 
 
); 
 
}; 
 

 
// Parent Class Component 
 
class ParentComponent extends React.Component { 
 
    state = { 
 
    firstName: "HELCODE"  
 
    }; 
 

 
    handleChange = event => { 
 
    this.setState({ 
 
     firstName: event.target.value, 
 
    }); 
 
    }; 
 
    
 
    render() { 
 
    const {title} = this.props; 
 
    console.log("rendered"); 
 
    return (
 
     <div> 
 
     <h3>{title}</h3> 
 
     <StatelessComponent 
 
      label="This is a label passed to a stateless component as prop" 
 
     /> 
 
     <br/> 
 
     <InputComponent 
 
      name={this.state.firstName} 
 
      handleChange={this.handleChange} 
 
     /> 
 
     
 
     <p>{this.state.firstName}{this.state.lastName} can read stuff from stateless components withough Ref using States</p> 
 
     <br/> 
 
     
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
// Render it 
 
ReactDOM.render(
 
    <ParentComponent title="Parent Component" />, 
 
    document.getElementById("react") 
 
);
<div id="react"></div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

0

只需添加一个解决方案,使用反应语意UI任何人。

https://react.semantic-ui.com/addons/ref

你可以简单地包裹无状态的功能组件在此Ref组件以获得DOM节点。

(非常有用的应对Sidebar.Pushable的滚动位置!)