0

I'm new to REACT and I'm having trouble trying to figure out not only the onChange event props, but many of the others. Its the props being passed in thats getting me. eg

handleSubmit(e) {
  let s = this.state;
  s.data[e.target.name] = e.target.value;
  this.setState(s);
}

its given like this in pretty much all the examples I have seen (the declaration of the function) and always complains about e in the function def as being implicitly an 'any' type. If I declare it as e:any it stops complaining, but then I cant get the s.data[e.target.name] to work as it says I cant have an 'any' type as an index. I cant figure out how it's meant to be declared, or if I have a configuration issue somewhere. It works if I replace e.target.name with a string constant like 'myarray'.

The REACT app was generated with a plain

npx create-react-app test --template typescript

with no changes to the generated configuration files.

The state was declared as

state = {
  data: { fldName: 'something', anotherField: 'somethingelse'}
}

Any ideas ?

Andrew
  • 113
  • 2
  • 8
  • Does this answer your question? [typesafe select onChange event using reactjs and typescript](https://stackoverflow.com/questions/33256274/typesafe-select-onchange-event-using-reactjs-and-typescript) – cbr May 28 '20 at 12:46
  • 1
    It's another problem but you are mutating the state in this piece of code doing state.data[...] = ..., you should not do this : https://reactjs.org/docs/react-component.html#state – Florian Motteau May 28 '20 at 12:46
  • cbr, that makes sense and I sort of figured something like that. Is there somewhere where these standard event types are documented as I haven't been able to find anything. – Andrew May 28 '20 at 12:49
  • Florian, yes, I know you're not meant to mutate the state, that's why I made a copy of it, then used setState, but I'm guessing I have done it in a way that has s pointing to state rather than having a copy of it, or are you referring to the initialisation I had. That was being done inside the class definition but outside of a function. Is this not the correct way to initialise the state ? – Andrew May 28 '20 at 12:53

3 Answers3

0

Try changing let s = this.state; to let s = Object.assign({}, this.state);. If you are changing it rather than copying it, that will be a reason it might not work. You may need to also do s.data = { ...s.data, [e.target.name]: e.target.value } which is doing the same thing to s.data, I usually keep my state flat.

Dave Ankin
  • 1,060
  • 2
  • 9
  • 20
  • Thanks for that assist. That seems to have helped, but I'm now starting to think that the event gets called before I have assigned the initial values to state. If I test the value of e.target.name to make sure it contains a valid value, then the code works. – Andrew May 28 '20 at 13:31
0

First of all, Welcome to the awesome React world.

Advice: You can include on your ticket the react version that you are using on your code.

It seems that you are using an old React version because now we have React hooks that allow us to use useState and other interesting stuff.

This is the React hooks documentation: https://reactjs.org/docs/hooks-intro.html

Related to your problem I think that you should take a look at the setState documentation: https://reactjs.org/docs/react-component.html#setstate

setState method receives a function that provides the updated state, below I have included a little example using your code, on this way you are making sure that the state that you are updating the proper state.

class TestComponent extends React.Component {
  constructor() {
    this.state = {
      test: true,
      data: {},
    };
  }

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

  render(){
      return <div>Test</div>
  }
}
rrios
  • 41
  • 5
0

I finally found my problem (or at least how to make my sample work).

in tsconfig.json I added the following compilerOption

"suppressImplicitAnyIndexErrors": true

this code now works

  upd = (e:React.ChangeEvent<HTMLSelectElement>) => {
    let qq = Object.assign({}, this.state);
    qq.frm[e.target.name] = e.target.value;
    this.setState(qq);
  }

wheres previously the line

qq.frm[e.target.name] = e.target.value;

failed saying

Parameter 'e' implicitly has an 'any' type. TS7006
Andrew
  • 113
  • 2
  • 8