2

Consider the following component src/src/components/year.tsx:

import React from 'react';

interface YearComponentProps {
  changeYear: Function;
  year: number;
  allowBefore: boolean;
}

const YearComponent: React.FC<YearComponentProps> = (props: YearComponentProps) => {
  let nowYear: number = props.year;
  const startYear: number = (props.allowBefore) ? nowYear - 100 : nowYear;
  const years: Array<number> = [];

  for (let i = startYear; i <= props.year + 100; i++) {
    years.push(i);
  }

  return (
    <div className="year-component">
      <select value={nowYear} onChange={(e) => props.changeYear(e)}>
        {years.map(yr => {
          return (<option key={yr} value={yr}>{yr}</option>);
        })}
      </select>
    </div>
  );
}

export default YearComponent;

I also have an index file src/src/index.tsx with the following:

import * as React from 'react';
import YearComponent from './components/year';

interface BaseProps {}

interface BaseState {
  currentYear: number;
}

class BaseComponent extends React.Component<BaseProps, BaseState> {
  readonly state: BaseState = {
    currentYear: this.initYear(),
  }

  initYear() {
    const today = new Date();
    return today.getFullYear();
  }

  changeYear(event: React.SyntheticEvent) {
    console.log(event.target.value);
  }

  render() {
    return (
      <div className="base-component">
        <YearComponent
          changeYear={this.changeYear}
          year={this.state.currentYear}
        />
      </div>
    );
  }
}

export default BaseComponent;

So what I want to do is when the user makes a change in the select box, the parent component should update its state with the new year. But I don't understand how to read the year on select. As you can see, I tried console.log(event.target.value); but this gives me an error:

index.js:1375 E:/Projekt/react-datepicker-clean-container/src/src/index.tsx
TypeScript error in E:/Projekt/react-datepicker-clean-container/src/src/index.tsx(214,30):
Property 'value' does not exist on type 'EventTarget'.  TS2339

    19 | 
    20 |   changeYear(event: React.SyntheticEvent) {
  > 21 |     console.log(event.target.value);
       |                              ^
    22 |   }
    23 | 
    24 |   render() {

I thought that using event.target.value was the correct way. Printing event.target just gives me the HTML-code for the select box. I tried using (<HTMLInputElement>event.target).value as stated in Property 'value' does not exist on type EventTarget in TypeScript but that did not help me in any way at all.

Can anyone wee what I am doing wrong?

BluePrint
  • 1,926
  • 4
  • 28
  • 49
  • *"I thought that using event.target.value was the correct way."* It is, note that the error is coming from TypeScript. It's a type issue. `SyntheticEvent`'s `target` is just an `HTMLElement`, which doesn't have a `value` property because that's only on `HTMLInputElement`s. See the linked questions' answers for details. – T.J. Crowder Nov 23 '19 at 16:57
  • You *used* to have to use a type assertion, but [this answer](https://stackoverflow.com/a/42085792/157247) shows how with more recent versions of React typings, you can use `React.FormEvent` as your event type. Its `target` will be a `HTMLSelectElement`, so you can use `value`. – T.J. Crowder Nov 23 '19 at 17:01
  • 1
    @T.J.Crowder I saw your link to the other question. I did not find it while googling, searhing here and writing my question, but doing it like that question worked. Thanks. – BluePrint Nov 23 '19 at 17:01
  • Glad that helped! Note that I added a second one which seems to be more up-to-date (I removed some stuff from the first comment above and posted the second). Happy coding! – T.J. Crowder Nov 23 '19 at 17:03

0 Answers0