Пользовательский интерфейс материала - Невозможно ввести текстовое поле ввода / задать значения в управляемом компоненте

Я попытался создать настраиваемый компонент ввода с inputRef (компонент ввода пользовательского интерфейса материала). Похоже, что ссылка на компонент работает, но я не могу ввести какое-либо значение в текстовое поле после того, как установил атрибут значения. Я думаю, это из-за того, как я реализовал событие onchange. Я не уверен, что мне не хватает. Пожалуйста помоги.

Вот URL-адрес codeandbox

https://codesandbox.io/s/pjlwqvwrvm

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
9 481
3

Ответы 3

На самом деле вам не нужна опора onChange, чтобы получить измененное значение.

Просто получите значение из onchange и установите значение в состояние value.

Другая ошибка заключается в том, что вы не создали конструктор, а присвоили this.props.value свойству value. Вот и не обновляйся ..

Теперь я создал конструктор и присвоил this.state.value свойствам значения.

Теперь вы получаете свое onchanged значение в компоненте custominput, а также функцию отправки.

import React from "react";
import { render } from "react-dom";
import { Input } from "material-ui-next";
import trimStart from "lodash/trimStart";
import PropTypes from "prop-types";

const defaultProps = {
  state: "",
  onChange: () => {} // no need
};

const propTypes = {
  state: PropTypes.string,
  onChange: PropTypes.func
};

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      value:''
    }
  }
  handleSubmit(event) {
    event.preventDefault();
    console.info("state: " + this.state.value); //shows onChanged value in console
  }

  render() {
    return (
      <div>
        <form onSubmit = {this.handleSubmit.bind(this)}>
          <CustomInput
            labelText = "State"
            id = "state"
            value = {this.state.value}
            onChange = {e=> {
              this.setState({value:e.target.value})
            }}
          />
        </form>
      </div>
    );
  }
}

App.propTypes = propTypes;
App.defaultProps = defaultProps;

class CustomInput extends React.Component {
  render() {
    const {
      classes,
      formControlProps,
      value,
      onChange,
      labelText,
      id,
      labelProps,
      inputRef,
      inputProps
    } = this.props;
    return (
      <div {...formControlProps}>
        {labelText !== undefined ? (
          <div htmlFor = {id} {...labelProps}>
            {labelText}
          </div>
        ) : null}
        <Input
          classes = {{
            root: labelText !== undefined ? "" : classes.marginTop
          }}
          id = {id}
          value = {value} ///////// Fixed ////////
          onChange = {onChange}
          inputRef = {inputRef}
          {...inputProps}
        />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

Вот код в песочнице проверьте ..

https://codesandbox.io/s/84rjk4m8l8

  1. Вы можете либо перейти на inputRef - тогда ваше значение и событие onChange будут дополнительными - это называется неконтролируемым компонентом. Вы можете узнать об этом подробнее здесь: https://reactjs.org/docs/uncontrolled-components.html

  2. Или вы можете сделать это с помощью события value и onChange - и работать с контролируемыми компонентами, вы можете найти больше об управляемых компонентах здесь: https://reactjs.org/docs/forms.html#controlled-components

Как решить (неконтролируемый) с inputRef:

class App extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault();
    console.info("input value: ", this.input.value); // will now show you correct input value
  }

  render() {
    return (
      <div>
        <form onSubmit = {this.handleSubmit}>
          <CustomInput
            labelText = "State"
            id = "state"
            inputRef = {input => {
              this.input = input;
            }}
          />
          <Button onClick = {this.handleSubmit} color='primary'>Submit</Button>
        </form>
      </div>
    );
  }
}

Вместо this.state = input привяжите ввод к чему-то еще, потому что this.state зарезервирован для локального состояния компонента React, и он не будет работать с ним, не так.

Как решить эту проблему (управляемую) с помощью состояния, значения и события onChange:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: props.state || ''
    }
  }

  handleSubmit = (event) =>{
    event.preventDefault();
    console.info("state: ", this.state.value); // will now show you correct input value
  }

  handleChangeEvent = (event) => {
    this.setState({value: event.target.value});
  }

  render() {
    const {value} = this.state;

    return (
      <div>
        <form onSubmit = {this.handleSubmit}>
          <CustomInput
            labelText = "State"
            id = "state"
            onChange = {this.handleChangeEvent}
            value = {value}
          />
          <Button onClick = {this.handleSubmit} color='primary'>Submit</Button>
        </form>
      </div>
    );
  }
}

Обратите внимание, что я добавил конструктор и определил локальное состояние для компонента, и я изменяю значение внутри состояния с помощью this.setState (потому что состояние неизменяемо, и это правильный способ его обновить).

В обоих примерах вы можете получить входное значение внутри метода handleSubmit, будете ли вы работать с контролируемыми или неконтролируемыми компонентами, решать вам :)

Используйте value = {this.state} или value = {this.value}

Вот ваш код песочницы обновлен

https://codesandbox.io/s/qqk2qoxmlj

Другие вопросы по теме