Как использовать функцию обработчика для двух разных целей. SPFX (React / TypeScript) - PullRequest
1 голос
/ 08 января 2020

Я создаю форму SPFX (реагировать / Typescript). Я использую функцию обработчика:

public handleChange = (evt: any) => {
    const {value} = (evt.target as any);

    this.setState({
      ...this.state,
      [evt.target.name]: value
    });
  }

Для обработки нескольких текстовых полей.

Теперь я хочу, чтобы этот обработчик обслуживал текстовые поля с количеством символов. (Я знаю, что мог бы использовать метки!) Эти текстовые поля подсчитывают, сколько символов было введено в каждое текстовое поле. Я не знаю, как написать код для этого. Ниже я попробовал:

Функция обработчика:

public handleChange = (evt: any) => {
    const {value} = (evt.target as any);

    this.setState({
      ...this.state,
      [evt.target.name]: value
    }, () => {
      let wordCount = this.state.SOMETHING.toString().length; //This is wrong!
      this.setState({
        ...this.state,
        [evt.target.name]: wordCount
    });
  });
}

Но, как вы можете видеть, я не совсем понимаю, что ставить. Как вы можете видеть с помощью переменной wordCount, я подсчитываю количество символов для состояния текстового поля, но это, очевидно, не сработает, потому что оно мне нужно для обслуживания ВСЕХ текстовых полей, которые проходят через функцию-обработчик. Вы также можете видеть, что я пытаюсь установить это состояние, используя [evt.target.name]: wordCount, это, я думаю, ближе к правильности. Но не уверен.

И если это поможет, вот 2 текстовых поля, одно из которых является текстовым полем ввода пользователя, а другое (под ним) - счетчик символов:

  <td><TextField
        name="EssCrit1"
        value={this.state.EssCrit1}
        onChange={this.handleChange}
        multiline rows={2}
     />
 </td>

   <td ><TextField 
        name="EssCritChars1"
        value={this.state.EssCritChars1}
        disabled={true}           
      />
 </td>

Как вы можете видеть, что счетчик символов имеет свое собственное состояние, но, как уже упоминалось выше, как мне получить функцию обработчика, чтобы обрабатывать это, а также событие onChange для текстового поля пользовательского ввода?

Любая помощь будет полезна как всегда.

C

Ответы [ 2 ]

2 голосов
/ 08 января 2020

Если вы хотите обработать любое значение данного текстового поля и длину значения:

public handleChange = (evt: any) => {
    const {value} = (evt.target as any);

    this.setState({
      [evt.target.name]: value,
      `${evt.target.name}Count`: value.toString.length,
    });
}
1 голос
/ 08 января 2020

Если я правильно понимаю, вы можете добавить в параметр onChange дополнительный параметр с именем соответствующего счетчика следующим образом:

<TextField
  name="EssCrit1"
  value={this.state.EssCrit1}
  onChange={this.handleChange('EssCritChars1')} // curry the name of the counter like this
  multiline rows={2}
/>

// We'll use counterName to update the correct counter state value
handleChange = (counterName: string) => (evt: any) => {
    const {value} = (evt.target as any);

    this.setState({
      [evt.target.name]: value
    }, () => {
      let wordCount = this.state[evt.target.name].toString().length; // Access as an array to use dynamic keys
      this.setState({
        [counterName]: wordCount // now we have a separate counter variable
    });
  });
}

Или же вы можете использовать встроенную функцию с необязательный второй параметр, подобный этому:

// Text field that has a counter
<TextField
  name="EssCrit1"
  value={this.state.EssCrit1}
  onChange={(e) => this.handleChange(e, 'EssCritChars1')} // Inline. Pass event and name of counter
  multiline rows={2}
/>
// Text field that doesn't need a counter
<TextField
  name="another_field"
  value={this.state.another_field}
  onChange={this.handleChange} // We only need the event so don't bother creating an inline function
  multiline rows={2}
/>

// Second param is optional
handleChange = (evt: any, counter = '') => {
  const {value} = (evt.target as any);
  let newState = {
    [evt.target.name]: value
  }
  if (counter) {
    newState[counter] = value.toString().length
  }
  this.setState(prevState => ({...prevState, newState });
}
...