Как использовать одно событие handleChange для нескольких текстовых полей? - PullRequest
0 голосов
/ 02 апреля 2020

В следующем коде у меня установлено TextField «Имя поставщика» для всех букв верхнего регистра. Если я хочу добавить это в TextField «Комментарии», я знаю, что могу просто добавить больше событий handleChange и назвать их по-другому. Есть ли способ использовать одно и то же событие handleChange для нескольких TextFields, так как я хочу сделать одно и то же?

import * as React from "react";
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface StackOverflowState {
    value: string;
  }
  export default class StackOverflow extends React.Component<{}, StackOverflowState> {
    public state: StackOverflowState = { value: '' };
    render() {
      this.handleChange = this.handleChange.bind(this);
      ;

      return (
        <div className="ms-welcome">
            <TextField 
                label="Supplier Name"
                styles={{ root: { width: 150 } }}
                onChange={this.handleChange.bind(this)}
                value={this.state.value}
            />
            <TextField 
                label="Comments"
                styles={{ root: { width: 300 } }}
            />
        </div>
      );
    }
    handleChange(event) {
      this.setState({value: event.target.value.toUpperCase()});
    }
  }

Ответы [ 4 ]

2 голосов
/ 02 апреля 2020

Некоторые замечания:

  • не используйте .bind(this) внутри render (), опционально используйте функцию стрелки.
  • используйте constructor() для инициализации классического компонента.
  • общая функция-обработчик с идентификатором индекса передана в качестве параметра.
  • используйте [key: string]: State[keyof State], чтобы разрешить выбор атрибута по строке.

Далее, мы может:

  • использовать массив состояний
  • использовать локальный HO C, чтобы избежать повторения себя в индексе
  • использовать массив для генерации визуализированных элементов
import * as React from "react";
import { TextField } from "office-ui-fabric-react/lib/TextField";

export interface State {
  [key: string]: State[keyof State];
  inputA: string;
  inputB: string;
}
export default class App extends React.Component<{}, State> {
  constructor(props: {}) {
    super(props);
    this.state = {
      inputA: "",
      inputB: ""
    };
  }
  handleChange = (field: string) => (event: any) => {
    const value = event.target.value.toUpperCase();
    this.setState({ [field]: value });
  };
  render() {
    console.log(this.state);
    return (
      <div className="ms-welcome">
        <TextField
          label="Supplier Name"
          styles={{ root: { width: 150 } }}
          onChange={this.handleChange("inputA")}
          value={this.state["inputA"]}
        />
        <TextField
          label="Comments"
          styles={{ root: { width: 300 } }}
          onChange={this.handleChange("inputB")}
          value={this.state["inputB"]}
        />
      </div>
    );
  }
}

Edit peaceful-mestorf-xbj6x

1 голос
/ 02 апреля 2020

Для обработки нескольких входов с помощью одного обработчика событий. Вам необходимо присвоить уникальные имена входным значениям, и вы можете записать изменение дескриптора на основе уникальных имен.

<div className="ms-welcome">
        <TextField 
            name="input1"
            onChange={this.handleChange.bind(this)}
            value={this.state.value}
        />
        <TextField 
            name="input2"
            onChange={this.handleChange.bind(this)}
            value={this.state.value}
        />
    </div>

Теперь вы можете просто записать изменение дескриптора на основе уникальных имен, примененных к полям ввода

HandleChange (e) {
 this.setState({[e.target.name]: e.target.value})
}

Когда событие приходит от первого входа, e.target.name будет входом1, а когда событие приходит от второго входа, e.target.name будет входом 2.

1 голос
/ 02 апреля 2020

Попробуйте использовать привязку немного больше:)

import * as React from "react";
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface StackOverflowState {
    value: string;
    comments: string;
  }
  export default class StackOverflow extends React.Component<{}, StackOverflowState> {
    public state: StackOverflowState = { value: '', comments: '' };

    private const handleChange = (stateField: keyof StackOverflowState) => (event) {
      this.setState({ [stateField]: event.target.value.toUpperCase()});
    }

    render() {
      return (
        <div className="ms-welcome">
            <TextField 
                label="Supplier Name"
                styles={{ root: { width: 150 } }}
                onChange={this.handleChange('value')}
                value={this.state.value}
            />
            <TextField 
                label="Comments"
                onChange={this.handleChange.('comments')}
                styles={{ root: { width: 300 } }}
            />
        </div>
      );
    }
  }

1 голос
/ 02 апреля 2020

Вы можете использовать объект в качестве состояния, содержащий ключи в качестве имен полей и значений для соответствующих имен полей

state = { values : {} };

onChange = (name, e) => {
   this.setState(state => ({ values: { ...state.values, [name]: e.target.value } }));

  // If e.target.name contains field name, no need to add extra name parameter in this method, you can use that as name

}

     <TextField 
            label="Supplier Name"
            styles={{ root: { width: 150 } }}
            onChange={e => this.handleChange('supplierName', e)}
            value={this.state.values.supplierName}
        />
 <TextField 
            label="Comments"
            styles={{ root: { width: 300 } }}
            onChange={e => this.handleChange('comments', e)}
            value={this.state.values.comments}
        />
...