reactjs - React Typescript videregivelse af props og datatype


Jeg er stadig ret ny i TypeScript-verdenen, og jeg har et par spørgsmål. Jeg har nogle fejl i min kode, og jeg er ikke helt sikker på, hvordan jeg skal sende props og vælge den rigtige type. Jeg ville sætte pris på lidt hjælp med det.

Har du måske en god kilde, hvor jeg kan finde alle de nødvendige oplysninger om React på ét sted, bare til starten?

tl;dr

  1. Hvad vil { data }-typen være? Hvordan definerer man den?
  2. Hvordan videregiver man funktionerne som props til Results.tsx-filen? Hvordan definerer man result, results og openPopup i denne funktion?
  3. Gik jeg glip af noget andet?

App.tsx

 import React, { useState } from 'react'
import axios from 'axios'

import Search from './components/Search'
import Results from './components/Results'
import Popup from './components/Popup'


export type selected = {
    Title?: string,
    Year?:number
}

type values = {
s: string,
results: string[],
selected: selected,
}

interface popup {
    id: string
}

const App: React.FC = () => {
  const [state, setState] = useState<values>({
    s: "",
    results: [],
    selected: {}
  });


  const apiurl = "http://www.omdbapi.com/?apikey=dfe6d885";

  const search = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      axios(apiurl + "&s=" + state.s).then(({ data }) => {
        let results = data.Search;

        setState(prevState => {
          return { ...prevState, results: results }
        })
      });
    }
  }
  
  const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    let s = e.target.value;

    setState(prevState => {
      return { ...prevState, s: s }
    });
  }

  const openPopup = (id : string) => {
    axios(apiurl + "&i=" + id).then(({ data }) => {
      let result = data;

      console.log(result);

      setState(prevState => {
        return { ...prevState, selected: result }
      });
    });
  }

  const closePopup = () => {
    setState(prevState => {
      return { ...prevState, selected: {} }
    });
  }

  return (
    <div className="App">
      <header>
        <h1>Movie Database</h1>
      </header>
      <main>
        <Search handleInput={handleInput} search={search} />

        <Results results={state.results} openPopup={openPopup} />

        {(typeof state.selected.Title != "undefined") ? <Popup selected={state.selected} closePopup={closePopup} /> : false}
      </main>
    </div>
  );
}

export default App

Results.tsx

import React from 'react'

import Result from './Result'

function Results ({ results, openPopup }) {
    return (
        <section className="results">
            {results.map(result => (
                <Result key={result.imdbID} result={result} openPopup={openPopup} />
            ))}
        </section>
    )
}

export default Results

Svar #1

Prop-typer

Du kan definere de props, som du sender til en funktionel komponent inline

function Results ({ results, openPopup }: { results: MyResult[], openPopup: () => void }) {

Men det er mere almindeligt at definere en separat interface for props

interface Props {
    results: MyResult[];
    openPopup: () => void;
}

Som du kan bruge til direkte at definere props

function Results ({ results, openPopup }: Props) {

Eller gennem React.FC

const Results: React.FC<Props> = ({ results, openPopup }) => {

Datatype

For at definere typen for data skal du oprette et interface, der har alle de egenskaber i API-responsen, som du ønsker at bruge. Derefter, når du kalder axios, bruger du den generiske type af axios-funktionen for at fortælle, hvordan de hentede data skal se ud.

Af en eller anden grund ser axios() ikke ud til at acceptere en generisk type, men axios.get() gør.

axios.get<MyApiResponse>(apiurl + "&s=" + state.s).then(({ data }) => {

Nu har data-variablen automatisk MyApiResponse-typen.

Relaterede artikler