反应无状态组件this.refs..value?

时间:2016-05-17 03:04:27

标签: reactjs

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

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

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>
    )
  }
}

这是无状态输入字段

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>
)

8 个答案:

答案 0 :(得分:52)

您可以在无状态组件中使用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>
  )
}

注意:虽然这是一种方法,但是,除非您确实需要,否则不建议使用此方法。尝试更多地考虑重新设计React代码,而不是像这样破解它。您可以阅读更多相关信息here

答案 1 :(得分:13)

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

无状态组件中的参考号不可用。 来自React Docs

  

由于无状态函数没有后备实例,因此无法将ref附加到无状态函数组件。通常这不是问题,因为无状态函数不提供命令性API。如果没有命令式API,那么无论如何都无法对一个实例做很多事情。但是,如果用户想要找到无状态函数组件的DOM节点,则它们必须将组件包装在有状态组件(例如,ES6类组件)中,并将ref附加到有状态包装器组件。

答案 2 :(得分:6)

从反应16.8起,您可以使用useRef钩子, from the docs

  

useRef返回一个可变的ref对象,其.current属性已初始化为传递的参数(initialValue)。返回的对象将在组件的整个生命周期内保持不变。

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

答案 3 :(得分:3)

@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>
  )
}

答案 4 :(得分:1)

如今,您希望avoid to use the ref attribute从输入字段中获取值。相反,你应该使用React的本地状态。 ref属性仅保留给few use cases

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

答案 5 :(得分:1)

你不能在无状态反应组件中使用refs(从文档中获取他的代码片段的Moti Azu +1)。

您可以使用多种技术将内容输入/输出无状态组件(不使用Ref或使用类组件),我已创建下面的代码片段来说明

  1. 如何将内容传递给无状态组件(标签在父组件中静态设置)。
  2. 如何在不使用refs(输入组件)的情况下从无状态组件中获取内容
  3. 尝试一下&amp;如果你还有问题请告诉我,享受......

    &#13;
    &#13;
    // 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")
    );
    &#13;
    <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>
    &#13;
    &#13;
    &#13;

答案 6 :(得分:0)

只为为使用react-semantic-ui的任何人添加解决方案。

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

您可以简单地将无状态功能组件包装在此Ref组件中以检索DOM节点。

(处理Sidebar.Pushable的滚动位置非常有用!)

答案 7 :(得分:-1)

import React, { useEffect, useRef } from 'react';

function TextFocusTest () {
  const textRef = useRef(null);

  useEffect(() => {
     textRef.current.focus();
  });

  return(
    <input ref{textRef} type="text">
  );

} 

export default TextFocusTest;