reactjs - Egenskap är odefinierad när man använder 'map'


Jag försöker skapa en sökkomponent som kontrollerar JSON från API:et (för närvarande bara en mock). Komponenten laddas korrekt, men när jag börjar skriva i sökfältet kraschar appen med felet "Uncaught (in promise) TypeError: Cannot read property of 'map' of undefined".

Jag har sett till att fälten är allihop desamma. Som nämnts laddas komponenten korrekt, men misslyckas när förslaget ska laddas. Så problemet är uppenbarligen i den här filen, men jag kan inte förstå varför den inte kan mappa resultaten.

Här är min sökkomponent:

// Imports

class Search extends Component {
    state = {
        query: '',
        results: []
    }

    getInfo = () => {
        axios.get('https://jsonplaceholder.typicode.com/users')
            .then(({data}) => {
                this.setState({
                    results: data.data
                })
            })
    }

    handleInputChange = () => {
        this.setState({
            query: this.search.value
        }, () => {
            if (this.state.query && this.state.query.length > 1) {
                if (this.state.query.length % 2 === 0) {
                    this.getInfo()
                }
            } else if (!this.state.query) {

            }
        })
    }

    render() {
        return (
            <form>
                <input
                    placeholder="Search for..."
                    ref={input => this.search = input}
                    onChange={this.handleInputChange}
                />
                <Suggestions results={this.state.results} />
            </form>
        );
    }
}
export default Search;

Sedan komponenten Suggestions som används i komponenten Search:

import React from 'react';

const Suggestions = (props) => {
    const options = props.results.map(r => (
        <li key={r.id}>
            {r.name}
        </li>
    ))
    return <ul>{options}</ul>
}
export default Suggestions;

Det idealiska resultatet skulle vara att Sökningen filtrerar baserat på inmatningen.

Svar #1

Ibland är det mest uppenbara svaret det korrekta. Om props.results är odefinierat, och dess värde kommer från state.results, då måste state.results vara odefinierat.

Jag testade din kod, och så länge state.results var en array fungerade allt utmärkt. Jag skulle kontrollera för att säkerställa att data.data verkligen är rätt plats att hämta dina resultat från (kanske räcker det med bara data?).

Om resultatet legitimt ibland är odefinierat, kontrollera då det resultatet och returnera en tom array:

getInfo = () => {
  axios.get('https://jsonplaceholder.typicode.com/users')
    .then(({data}) => {
       this.setState({
         results: data.data || [] // <-- now never undefined.
       })
    });
}

Svar #2

Det största problemet du har här är att du redan har destrukturerat data från axios-svaret, så du behöver inte använda data.data, använd bara data i ditt setState()-anrop. data.data är alltid undefined och därför misslyckas det med Cannot read property of 'map' of undefined.

För det andra skulle jag inte använda en ref för ett så enkelt fall. Du kan hämta inmatningselementet och dess värde från själva händelsen (du får det som det första argumentet i handleInputChange()-metoden).

Med detta i åtanke skulle jag göra Search-komponenten så här:

class Search extends React.Component {
  state = {
    query: "",
    results: []
  };

  getInfo = () => {
    axios.get("https://jsonplaceholder.typicode.com/users").then(({ data }) => {
      this.setState({
        results: data
      });
    });
  };

  handleInputChange = event => {
    this.setState(
      {
        query: event.target.value
      },
      () => {
        if (this.state.query && this.state.query.length > 1) {
          if (this.state.query.length % 2 === 0) {
            this.getInfo();
          }
        } else if (!this.state.query) {
        }
      }
    );
  };

  render() {
    return (
      <form>
        <input placeholder="Search for..." onChange={this.handleInputChange} />
        <Suggestions results={this.state.results} />
      </form>
    );
  }
}

export default Search;

Notera hur jag inte längre använder ref och hur datan nås.

Relaterade artiklar