I'm using Typescript with React for a project. The Main component gets passed state with this interface.
interface MainState { todos: Todo[]; hungry: Boolean; editorState: EditorState; //this is from Facebook's draft js }
However, the code below (only an excerpt) won't compile.
class Main extends React.Component<MainProps, MainState> { constructor(props) { super(props); this.state = { todos: [], hungry: true, editorState: EditorState.createEmpty() }; } onChange(editorState: EditorState) { this.setState({ editorState: editorState }); } }
The compiler complains that, in the onChange
method where I am only trying to setState for one property, the property todos
and the property hungry
is missing in type { editorState: EditorState;}
. In other words, I need to set the state of all three properties in the onChange
function to make the code compile. For it to compile, I need to do
onChange(editorState: EditorState){ this.setState({ todos: [], hungry: false, editorState: editorState }); }
but there's no reason to set the todos
and the hungry
property at this point in the code. What is the proper way to call setState on only one property in typescript/react?
The definitions for react were updated and the signature for setState
are now:
setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;
Where Pick<S, K>
is a built-in type which was added in Typescript 2.1:
type Pick<T, K extends keyof T> = { [P in K]: T[P]; }
See Mapped Types for more info.
If you still have this error then you might want to consider updating your react definitions.
I'm facing the same thing.
The two ways I manage to get around this annoying issue are:
(1) casting/assertion:
this.setState({ editorState: editorState } as MainState);
(2) declaring the interface fields as optional:
interface MainState { todos?: Todo[]; hungry?: Boolean; editorState?: EditorState; }
If anyone has a better solution I'd be happy to know!
While this is still an issue, there are two discussions on new features that will solve this problem:
Partial Types (Optionalized Properties for Existing Types)
and
More accurate typing of Object.assign and React component setState()
Update state explicitly, example with the counter
this.setState((current) => ({ ...current, counter: current.counter + 1 }))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With