Доступ к ссылкам в компоненте с состоянием не работает в React?
В настоящее время я пытаюсь реорганизовать учебник по простым задачам для метеора с использованием презентационных и контейнерных компонентов, но столкнулся с проблемой, пытаясь получить доступ к ссылкам input
в функциональном компоненте без состояния. Я узнал, что для доступа refs
, вы должны обернуть компонент в компонент с состоянием, что я сделал с input
,
// import React ...
import Input from './Input.jsx';
const AppWrapper = (props) => {
// ... more lines of code
<form className="new-task" onSubmit={props.handleSubmit}>
<Input />
</form>
}
import React, { Component } from 'react';
Этот Ввод должен быть с состоянием, потому что он использует синтаксис класса, по крайней мере, я думаю.
export default class Input extends Component {
render() {
return (
<input
type="text"
ref="textInput"
placeholder="Type here to add more todos"
/>
)
}
}
Я использую ссылки для поиска значения входа в охватывающих AppContainer
,
import AppWrapper from '../ui/AppWrapper.js';
handleSubmit = (event) => {
event.preventDefault();
// find the text field via the React ref
console.log(ReactDOM.findDOMNode(this.refs.textInput));
const text = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
...
}
Результатом console.log является null
, так что мой компонент ввода не с состоянием? Нужно ли устанавливать конструктор, который устанавливает значение для this.state
чтобы сделать этот компонент с состоянием, или я должен просто отказаться от использования функциональных компонентов без состояния, когда мне нужно использовать refs
?
2 ответа
Вы должны использовать компоненты с сохранением состояния при использовании ссылок. В вашем событии handleSubmit вы вызываете 'this.refs', когда поле находится в отдельном компоненте.
Чтобы использовать ссылки, вы добавляете ссылку туда, где вы визуализируете AppWrapper, и сам AppWrapper должен быть с состоянием.
Вот пример:
AppWrapper - это ваша форма
class AppWrapper extends React.Component {
render() {
return (
<form
ref={f => this._form = f}
onSubmit={this.props.handleSubmit}>
<Input
name="textInput"
placeholder="Type here to add more todos" />
</form>
);
}
};
Ввод - это многократно используемый компонент текстового поля
const Input = (props) => (
<input
type="text"
name={props.name}
className="textbox"
placeholder={props.placeholder}
/>
);
Приложение - это компонент контейнера
class App extends React.Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
const text = this._wrapperComponent._form.textInput.value;
console.log(text);
}
render() {
return (
<AppWrapper
handleSubmit={this.handleSubmit}
ref={r => this._wrapperComponent = r}
/>
);
}
}
http://codepen.io/jzmmm/pen/BzAqbk?editors=0011
Как вы можете видеть, компонент Input не имеет состояния, а AppWrapper имеет состояние. Теперь вы можете избежать использования ReactDOM.findDOMNode
и напрямую получить доступ к textInput. Вход должен иметь name
атрибут для ссылки.
Вы можете упростить это, переместив <form>
тег в компонент приложения. Это устранит один ref
,
или я должен просто отказаться от использования функциональных компонентов без состояния, когда мне нужно использовать ссылки?
Да. Если компоненты должны хранить ссылки на элементы, которые они отображают, они сохраняют состояние.
Ссылки могут быть установлены с помощью функции "обратного вызова" следующим образом:
export default class Input extends Component {
render() {
// the ref is now accessable as this.textInput
alert(this.textInput.value)
return (
<input
type="text"
ref={node => this.textInput = node}
placeholder="Type here to add more todos"
/>
)
}
}