reactjs 正在从firestore获取数据并设置为useEffect中的状态在第一次渲染中不起作用

yx2lnoni  于 2023-02-15  发布在  React
关注(0)|答案(3)|浏览(121)

以下代码用于从firebase firestore获取数据并在useEffect中设置为状态“products”:

const { firebase } = useContext(FirebaseContext)
  const [products, setProducts] = useState([])                                        
  const db=firebase.firestore();

  useEffect(() => {
    const unsubscribe = db.collection("products").onSnapshot((snapshot) => {
      const newProducts = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      setProducts(newProducts);
      console.log( products);
    });

    return () => unsubscribe();
  }, []);

当第一次渲染产品控制空数组时。(数据正确地从firestore获取并作为对象数组进入“newProducts”)。
在运行过程中,如果代码中发生了一些变化,服务器将重新启动,此时产品状态将正确控制。
而在刷新浏览器时,产品又被控制为空数组。
我希望“产品”状态是在useEffect的第一个工作中设置firestore的值
我来到这个状态更新渲染我的组件如下..

return
           <div>
            <h4>{product.name}</h4>
            <p> {product.price}</p>
            <p>{product.type}</p>
             </div>
    })
    }

所有这些都没有运行,因为产品状态在初始渲染时为空...提示:这是因为setproduct()的异步特性。我如何才能使代码在这样一种方式,页面加载后,才设置的状态..我如何才能解决这个问题..?

rjzwgtxy

rjzwgtxy1#

这是因为组件还没有重新呈现,产品状态仍然显示以前的值,如果您想查看它的值,请在useffect之外使用它,或者在setProduct回调中记录prevState以查看它的值
像这样:

useEffect(() => {
    const unsubscribe = db.collection('products').onSnapshot(snapshot => {
      const newProducts = snapshot.docs.map(doc => ({
        id: doc.id,
        ...doc.data(),
      }));
      setProducts(newProducts);
      setProducts((prevState)=>{
        console.log(prevState)
        return prevState
      });
    });

    return () => unsubscribe();
  }, []);

也可以使用另一个useEffect查看它的新值,如下所示:

useEffect(()=>{
    console.log(products);
  },[products])
wlzqhblo

wlzqhblo2#

console.log(products)移到声明产品的useState钩子之后的右侧。
react(setState)中的状态更新可能发生在asynchronously,因此,不能保证下一行具有更新后的状态,您真正关心的是组件呈现时的状态

7lrncoxx

7lrncoxx3#

您可以基于任何状态变量(例如productLoading)有条件地呈现组件。
您可以使用useState钩子和状态变量productLoading来解决这个问题。
您可以在组件开始时将productLoading设置为true,并在设置状态products之后将其设置为false。
下面是一个如何实现这一点的示例:

const { firebase } = useContext(FirebaseContext);
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const db = firebase.firestore();
useEffect(() => {
        const unsubscribe = db.collection("products").onSnapshot((snapshot) => {
        const newProducts = snapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setProducts(newProducts);
        setLoading(false);
      });
    
      return () => unsubscribe();
    }, []);
    
    return (
      <div>
        {loading ? (
          <div>Loading...</div>
        ) : (
          <ul>
            {products.map((product) => (
              <li key={product.id}>{product.name}</li>
            ))}
          </ul>
        )}
      </div>
    );

这将允许仅在产品数据可用后呈现组件

相关问题