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

IT技术 reactjs
2021-03-28 09:25:38

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

我知道在研究之后现在这不正确,但是您应该如何从这些输入字段中获取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>
    )
  }
}

这是无状态输入字段

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>
)
6个回答

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

这也是我的示例小提琴,向您展示了它是如何工作的。

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 代码,而不是像这样修改它。您可以在此处阅读更多相关信息

这应该是公认的答案。可能不是最佳设置,但对于您想要访问呈现的 DOM 节点的无状态功能控件,这与 2017 年 1 月一样好。
2021-05-29 09:25:38
@DanielZuzevich 否决正确答案是对这个社区的损害。问题是关于如何使用 refs 做到这一点,这是正确的答案。它没有询问推荐的方式。我们已经意识到这一点。
2021-06-04 09:25:38
我强烈不同意有 6 个赞成票的评论。截至 2017 年 1 月,这不是最佳方法。将输入字段存储在父组件状态中要安全得多。请阅读处理表格的官方文档。
2021-06-08 09:25:38
你确定是朋友?
2021-06-21 09:25:38
@MuhaiminAbdul 是的,我确定。看看我的小提琴:jsfiddle.net/inancgumus/dvfdj4wx
2021-06-21 09:25:38

从 react 16.8 开始,您可以使用文档中useRef钩子

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>
    </>
  );
}
无法使其在react 16.8.6. 是说Uncaught TypeError: textFieldRef.current.focus is not a function
2021-05-24 09:25:38
@Maris 您必须重新加载页面才能使 refs 处于活动状态,并且必须使用 react导入 useRef
2021-06-04 09:25:38

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

Refs 在无状态组件中不可用。来自React 文档

因为无状态函数没有支持实例,所以不能将 ref 附加到无状态函数组件。通常这不是问题,因为无状态函数不提供命令式 API。如果没有命令式 API,无论如何您都无法对实例做很多事情。但是,如果用户想要找到无状态函数组件的 DOM 节点,他们必须将组件包装在有状态组件(例如 ES6 类组件)中,并将 ref 附加到有状态包装器组件。

实际上,您可以从无状态组件中引用 dom 元素。来自文档: 但是,只要您引用 DOM 元素或类组件,就可以在功能组件内使用 ref 属性
2021-05-22 09:25:38

@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>
  )
}
非常有用的片段!谢谢你。
2021-05-28 09:25:38

如今,您可能希望避免使用 ref 属性从输入字段中获取值。相反,您应该使用 React 的本地状态。ref 属性仅保留用于少数用例

  • 管理焦点、文本选择或媒体播放
  • 与第三方 DOM 库集成
  • 触发命令式动画