简体   繁体   English

React 无状态组件 this.refs..value?

[英]React stateless component this.refs..value?

I don't know if I'm doing this correctly... If I want to get value from an input I use this.refs.whatever.value.trim() but if that input is a stateless function component how do I do retrieve the value onSubmit?我不知道我这样做是否正确......如果我想从输入中获取值,我使用 this.refs.whatever.value.trim() 但如果该输入是无状态函数组件,我该怎么做检索 onSubmit 的值?

I know this isn't correct now after researching but how are you supposed to get value from these input fields?我知道这在研究后现在不正确,但是您应该如何从这些输入字段中获取价值?

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

this is the stateless 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>
)

You can use ref s inside stateless components.您可以在无状态组件中使用ref

Here is also my example fiddle that shows you how it works.这也是我的示例小提琴,向您展示了它是如何工作的。

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

Note: Although this is one way to do it, however, this approach is not recommended unless you really need it.注意:虽然这是一种方法,但是,除非您确实需要,否则不建议使用这种方法。 Try to think about more on redesigning your React code instead of hacking it like this.尝试更多地考虑重新设计你的 React 代码,而不是像这样修改它。 You may read more about it here .您可以在此处阅读更多相关信息。

as of react 16.8 you can use the useRef hook, from the docs :从 react 16.8 开始,您可以使用来自文档useRef钩子:

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数 (initialValue)。 The returned object will persist for the full lifetime of the component.返回的对象将在组件的整个生命周期内持续存在。

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

Edit: Looks like this is not the issue anymore, since new ideas on how to handle this situation arose since this answer was written.编辑:看起来这不再是问题了,因为自从写下这个答案以来,出现了关于如何处理这种情况的新想法。 Refer to inanc's answer instead of this one.参考 inanc 的答案而不是这个答案。

Refs are unavailable in stateless components. Refs 在无状态组件中不可用。 From React Docs :来自React 文档

Because stateless functions don't have a backing instance, you can't attach a ref to a stateless function component.因为无状态函数没有支持实例,所以不能将 ref 附加到无状态函数组件。 Normally this isn't an issue, since stateless functions do not provide an imperative API.通常这不是问题,因为无状态函数不提供命令式 API。 Without an imperative API, there isn't much you could do with an instance anyway.如果没有命令式 API,无论如何您都无法对实例做很多事情。 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.但是,如果用户想要找到无状态函数组件的 DOM 节点,他们必须将组件包装在有状态组件(例如 ES6 类组件)中,并将 ref 附加到有状态包装器组件。

@inanc, show good method, but I propose an alternative way to use event target to get the DOM element reference. @inanc,展示了很好的方法,但我提出了一种使用事件目标来获取 DOM 元素引用的替代方法。 As you are using the form element, you can name your input elements and use it to access the form object.当您使用表单元素时,您可以命名输入元素并使用它来访问表单对象。

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

Nowadays, you would want to avoid to use the ref attribute to get values from input fields.如今,您可能希望避免使用 ref 属性从输入字段中获取值。 Instead you should use React's local state.相反,您应该使用 React 的本地状态。 The ref attribute is reserved for only a few use cases : ref 属性仅保留用于少数用例

  • Managing focus, text selection, or media playback管理焦点、文本选择或媒体播放
  • Integrating with third-party DOM libraries与第三方 DOM 库集成
  • Triggering imperative animations触发命令式动画

You can't use refs in stateless react components (+1 to Moti Azu for his snippet from the documentation).您不能在无状态反应组件中使用 refs(Moti Azu 为他的文档片段+1)。

You can use multiple techniques to get stuff in/out of stateless components (without using Ref or use class components), I have created the snippet below to illustrate您可以使用多种技术将内容输入/输出无状态组件(不使用 Ref 或使用类组件),我创建了下面的代码片段来说明

  1. How you can pass stuff into a stateless component (the label props set statically in the parent component).如何将内容传递到无状态组件(在父组件中静态设置的标签道具)。
  2. How you can get stuff from a stateless component without use of refs (the input component)如何在不使用 refs(输入组件)的情况下从无状态组件中获取内容

try it out & let me know if you still have a problem, enjoy...尝试一下,如果您仍有问题,请告诉我,享受...

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

just to add a solution for anyone that use react-semantic-ui. 只是为任何使用react-semantic-ui的人添加解决方案。

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

You can simply wrap the stateless functional component in this Ref component to retrieve the DOM node. 您可以简单地将无状态功能组件包装在此Ref组件中以检索DOM节点。

(very useful to deal with the scrolling position of a Sidebar.Pushable !) (非常有用的处理Sidebar.Pushable的滚动位置!)

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM