reactjs - Hur man definierar defaultProps i React 18 TypeScript utan valfria parametrar


När du använder funktionella komponenter i React rekommenderas det att inte längre använda Component.defaultProps. Standardvärden för props bör definieras i själva funktionsparametrarna, så här:

interface Props {
  foo?: string,
  bar?: string,
}

const Component: FC<Props> = ({ foo = 'hello', bar = 'world' }) => {
  return ...
}

Men detta fungerar bara när props har en optional ?-typ, som sedan sätts av parametrarna när ett värde är odefinierat. Vad händer om jag inte vill göra mina props valfria?

Till exempel kommer detta inte att fungera:

interface Props {
  importantProp: string,
}

const ImportantComponent: FC<Props> = ({ importantProp = 'not undefined' }) => {
  return ...
}

// usage
const SomeOtherComponent = () => {
   return <ImportantComponent />
   // ts-error -> Type '{}' is missing the following properties from type 'Props': importantProp.
}

Att definiera denna prop som optional medför vissa risker, eftersom den nu också är valfri när man definierar dess standardvärden. Någon kanske glömmer att skicka ett värde till den och nu kommer allt att gå sönder. (i värsta fall):

const ImportantComponent: FC<Props> = ({ importantProp = undefined }) => {}
// We can still set `importantProp` to undefined, which should never happen

Så, vad är en korrekt lösning där standardvärden för props kan definieras utan att sätta dem som valfria parametrar?

Svar #1

const Component: FC<Props> = ({ foo = 'hello', bar = 'world' }) => {

Anledningen till att sådan kod rekommenderas är för att den är bekväm. Det är en bra genväg för:

const Component: FC<Props> = (props) => {
  const foo = props.foo === undefined ? 'hello' : props.foo;
  const bar = props.bar === undefined ? 'world' : props.bar;

Men om du har något annat du vill göra, kan du skriva annan kod. Du säger i kommentarerna att du vill ha ett fördefinierat defaultProps-objekt, som sedan tillämpas på de saknade props. Det kan göras så här (bland andra möjligheter):

const defaultProps = {
  foo: 'hello',
  bar: 'world',
}

const Component: FC<Props> = (props) => {
  const propsWithDefaults = {
    ...defaultProps,
    ...props,
  }

  const { foo, bar } = propsWithDefaults;

Lekplatslänk

Om du vill att TypeScript ska kontrollera defaultProps-objektet för att se till att det inte har stavfel eller extra egenskaper och liknande, kan du använda satisfies-nyckelordet (infört i TypeScript 4.9):

const defaultProps = {
  fo: 'hello', // <--- oops, typo
  bar: 'world',
  baz: 'so' // <--- oops, extra property
} satisfies Partial<Props>

Lekplatslänk

Relaterade artiklar