尝试使用React钩子显示API中的数据时出现类型错误

时间:2020-03-04 03:53:21

标签: javascript reactjs api axios react-hooks

我要完成的工作是显示我进行的API调用中的数据(名称和电子邮件),然后通过在输入字段中输入要查看的名称来过滤()结果。

当我只是尝试显示名称列表时,或者在这种情况下,仅显示一个名称错误消息

TypeError:无法读取null的属性“ 0”

下面是我在这个简单应用程序中用于学习/测试的代码。

import React, { useEffect, useState } from "react";
import "./App.css";

import axios from "axios";

function App() {
  const [selected, setSelected] = useState(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    axios.get("https://jsonplaceholder.typicode.com/users").then(res => {
      setSelected(res.data);
    });
  }, []);

  console.log(selected);
  // console.log(selected.name)

  return (
    <div className="App">
      <div>Names below</div>
      <input
        type="text"
        value={search}
        onChange={e => {
          e.preventDefault();
          setSearch(e.target.value);

          const name = selected.filter(
            select => select.name === search,
            selected
          );
        }}
      />
      <div className="list">{selected[0].name}</div>
    </div>
  );
}

export default App;

3 个答案:

答案 0 :(得分:0)

在这里,因为您是在useEffect调用中进行axios调用,所以在useEffect调用发生之前,selected的值为null。 因此,由于selected.filter在null上运行(因为filter是数组的方法),因此它返回错误 因此,您需要将selected设置为默认值[],即 const [selected, setSelected] = useState([]);,或者如果selected的值为null,则需要在最终返回之前返回null,以便在填充selected的值之前不会呈现任何内容

if(!selected) {
  return null;
}

我添加了一个小提琴here

答案 1 :(得分:0)

定期访问https://codesandbox.io/s/long-platform-u81q3

可以选择的对象时呈现的名称部分确实存在。

答案 2 :(得分:0)

我想您可以在输入名称时对其进行过滤

import React, { useEffect, useState } from "react";
import "./styles.css";

import axios from "axios";

function App() {
  const [selected, setSelected] = useState(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    axios.get("https://jsonplaceholder.typicode.com/users").then(res => {
      setSelected(res.data);
    });
  }, []);

  console.log(selected);
  // console.log(selected.name)

  return (
    <div className="App">
      <div>Names below</div>
      <input
        type="text"
        value={search}
        onChange={e => {
          e.preventDefault();
          setSearch(e.target.value);
        }}
      />
      {selected &&
        selected
          .filter(
            select => select.name.toLowerCase().includes(search),
            selected
          )
          .map(select => <div className="list">{select.name}</div>)}
    </div>
  );
}

export default App;