使用“地图”时属性未定义

时间:2019-08-01 21:22:29

标签: reactjs typescript

我正在尝试创建一个搜索组件,以检查API的JSON(目前只是一个模拟)。组件加载正常,但是当我开始在搜索字段中键入内容时,应用程序崩溃,并显示错误“未捕获(承诺)TypeError:无法读取未定义'map'的属性”。

我已确保所有字段均相同。如前所述,组件可以正确加载,但是应该在建议加载后失败。因此,问题显然出在此文件中,但无法理解为什么它无法映射结果。

这是我的搜索组件:

// 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;

然后在搜索组件中使用“建议”组件:

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;

理想的结果是让搜索根据输入内容进行过滤。

2 个答案:

答案 0 :(得分:2)

有时候,最明显的答案是正确的答案。如果props.results未定义,且其值来自state.results,则state.results必须未定义。

我测试了您的代码,并且只要state.results是一个数组,一切都可以正常工作。我将检查以确保data.data确实是获取结果的正确位置(也许只是data可以解决问题?)。

如果有时合法地未定义结果,则检查该结果并返回一个空数组:

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

答案 1 :(得分:1)

这里最大的问题是您已经从axios响应中解构了数据,因此您不必使用data.data,在data中仅使用setState()呼叫。 data.data始终为undefined,这就是为什么它以Cannot read property of 'map' of undefined失败的原因。

第二,对于这种简单情况,我不会使用ref。您可以从事件本身获取输入元素及其值(您可以将其作为handleInputChange()方法的第一个参数)。

考虑到这一点,我将使Search组件看起来像这样:

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;

请注意如何不再使用ref以及如何访问数据。