reactjs - typescript derleyicisinin yalnızca bir react state özelliğini güncellemek için setState çağırmasına izin ver


Bir proje için React ile Typescript kullanıyorum. Main bileşenine bu arayüz ile durum iletiliyor.

interface MainState {
  todos: Todo[];
  hungry: Boolean;
  editorState: EditorState;  //this is from Facebook's draft js
}

Ancak, aşağıdaki kod (yalnızca bir alıntı) derlenmeyecek.

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
    });
  }
}

Derleyici, sadece bir özellik için setState yapmaya çalıştığım onChange metodunda, todos özelliği ve hungry özelliğinin { editorState: EditorState;} türünde eksik olduğunu belirtiyor. Başka bir deyişle, kodun derlenmesi için onChange fonksiyonunda tüm üç özelliğin durumunu ayarlamam gerekiyor. Derlemesi için yapmam gereken

onChange(editorState: EditorState){
  this.setState({
    todos: [],
    hungry: false,
    editorState: editorState
  });
}

ama bu noktada todos ve hungry özelliğini ayarlamak için bir sebep yok. TypeScript/React'te yalnızca bir özelliği güncellemek için setState'i çağırmanın doğru yolu nedir?

Cevap #1

Düzenle

React için tanımlar güncellendi ve setState için imza artık şunlardır:

setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;

Pick<S, K>, Typescript 2.1'de eklenen yerleşik bir türdür:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

Daha fazla bilgi için Haritalı Türlere bakın.
Eğer hâlâ bu hatayı alıyorsanız, react tanımlarınızı güncellemeyi düşünebilirsiniz.

Orijinal cevap:

Ben de aynı şeyle karşı karşıyayım.

Bu can sıkıcı sorunun üstesinden gelmeyi başardığım iki yol şunlardır:

(1) dönüştürme/doğrulama:

this.setState({
    editorState: editorState
} as MainState);

(2) arayüz alanlarını isteğe bağlı olarak tanımlamak:

interface MainState {
    todos?: Todo[];
    hungry?: Boolean;
    editorState?: EditorState;
}

Eğer birinin daha iyi bir çözümü varsa, bilmekten memnuniyet duyarım!

Düzenle

Bu hâlâ bir sorun olsa da, bu problemi çözecek yeni özellikler üzerine iki tartışma var:
Kısmi Tipler (Mevcut Tipler için İsteğe Bağlı Özellikler)
ve
Object.assign ve React bileşeni setState() için daha doğru tip tanımlamaları

Cevap #2

Durumu açıkça güncelle, sayaç ile örnek

this.setState((current) => ({ ...current, counter: current.counter + 1 }))

İlgili makaleler