使用 axios 和 useEffect 从 firebase 获取数据

时间:2021-03-16 20:46:45

标签: reactjs axios use-effect

我正在努力使用 axios 和 useEffect 从 firebase 数据库检索数据。这是一个简单的库存应用程序,发布请求工作正常。我可以在控制台中看到响应数据,但是我无法使用它。现在我得到了这个 TypeError: Function.prototype.apply was called on undefined。我试图从应用程序的其他功能中使用useEffect,但我似乎已经没有想法了。

ItemsList.js:

import React, { useContext, useState, useEffect } from 'react';
import Item from './Item';
import { ItemContext } from './ItemContext';
import axios from '../src/axios-items';

const ItemsList = () => {
  const { items } = useContext(ItemContext);
  
  const [setItems] = useState();
  useEffect(() => {
    axios.get('/items.json')
        .then(resp => {
                      console.log(resp.data);
                      const responseItems = resp.data
                      setItems(...items, responseItems)})
        .catch(error => console.log(error));
  }, [items, setItems]);

  return (
    <div className="items-list">
      {items.map(item => (
        <Item
          key={item.id}
          id={item.id}
          name={item.name}
          amount={item.amount}
        />
      ))}
    </div> 
   );
};
 
export default ItemsList;

ItemContext.js:

import React, { useState, createContext } from 'react';
import { v1 as uuidv1 } from 'uuid';

export const ItemContext = createContext({
  items: [],
  addItem: () => {},
  deleteItem: () => {}
});

const initialState = [
  {
    name: "Red Beans",
    amount: 23,
    id: uuidv1()
  },
  {
    name: "Nuts for Bunnies",
    amount: 33,
    id: uuidv1()
  },
  {
    name: "Chopped Tomatoes",
    amount: 2,
    id: uuidv1() 
  }
];

export const ItemProvider = (props) => {
  const [items, setItems] = useState(initialState);
  const addItem = (item) => setItems((items) => [...items, item]);
  
  const deleteItem = (id) => setItems((items) => items.filter((item) => item.id !== id));

  const value = {
    items,
    addItem,
    deleteItem
  };

  return ( 
      <ItemContext.Provider value={value} >
        {props.children}
      </ItemContext.Provider>
   );
};

AddItem.js:

import React, { useState, useContext } from 'react';
import { ItemContext } from './ItemContext';
import { v1 as uuidv1 } from 'uuid';
import axios from '../src/axios-items';

const AddItem = () => {
  const [name, setName] = useState('');
  const [amount, setAmount] = useState('');
  const { addItem } = useContext(ItemContext);

  const updateName = (e) => {
    setName(e.target.value)
  };

  const updateAmount = (e) => {
    setAmount(e.target.value)
  };

  const submitHandler = (e) => {
    e.preventDefault();
    addItem({
      name: name,
      amount: amount,
      id: uuidv1() // <-- new GUID here!!
    });
    const newItem = {
      name: name,
      amount: amount
    }
    axios.post('/items.json', newItem)
        .then(resp => console.log(resp))
        .catch(error => console.log(error));
    setName('');
    setAmount('');
  };

  return ( 
      <form className="new-item" onSubmit={submitHandler}>
        <input type="text" name="name" value={name} onChange={updateName} placeholder="Add a new item"/>
        <input type="text" name="amount" value={amount} onChange={updateAmount} placeholder="Amount"/>
        <button>Submit</button>
      </form>
   );
};

export default AddItem;

1 个答案:

答案 0 :(得分:0)

我认为要理解为什么这不起作用,您应该快速查看 react 文档中的 useStateuseEffect 挂钩。我认为这里的基本面可能需要刷新一下。


错误出在您的 ItemList.js 中,因此我将如何处理此问题:

useState 接受一个参数,该参数将是首次安装时 items 的默认值。:

    const [items, setItems] = useState([]);

如果您希望项目具有不同的默认值,只需将上面的空数组替换为它应该是的任何值,例如:

  // Alternate default value from context:
    const [items, setItems] = useState(useContext(ItemContext).items);
  // this should use the items property from context as the default value

现在,当第一次挂载组件时,获取项目并更新状态

  useEffect(() => {
    axios.get('/items.json')
        .then(resp => setItems(resp.data);
        .catch(console.log);
  }, []);

// Note that an empty array as a second argument for useEffect is equivalent to 
// the componentDidMount lifecycle step