admin管理员组

文章数量:1306875

This is my code. I want to add a new expense item at the top of the list. I was hoping to get some help on how I can create a new expense at the top of the list. I keep getting the same error: Too many re-renders. React limits the number of renders to prevent an infinite loop. How can I fix this?

import React, { useState } from "react";
import { Text, View, ScrollView } from "react-native";
import NewExpense from "../NewExpense";
import {
  selectTitle,
  selectPrice,
  selectCategory,
} from "../../slices/dataSlice";
import { useSelector } from "react-redux";

const RenderedExpense = () => {

  const title = useSelector(selectTitle);
  const price = useSelector(selectPrice);
  const category = useSelector(selectCategory);

  const enteredData = {
    id: Math.random().toString(),
    title: title.disTitle,
    price: price.disPrice,
    category: category.disCategory,
  };

  const expense = enteredData;

    const [expenseItems, setExpenseItems] = useState([]);
    setExpenseItems([expense, ...expenseItems]);


  return (
    <View>
      {
        (title.disTitle,
        price.disPrice,
        category.disCategory ? <NewExpense /> : null)
      }
      {
        expenseItems.map(() => {
          <NewExpense key={enteredData.id} /> })
      }
    </View>
  );
};

This is my code. I want to add a new expense item at the top of the list. I was hoping to get some help on how I can create a new expense at the top of the list. I keep getting the same error: Too many re-renders. React limits the number of renders to prevent an infinite loop. How can I fix this?

import React, { useState } from "react";
import { Text, View, ScrollView } from "react-native";
import NewExpense from "../NewExpense";
import {
  selectTitle,
  selectPrice,
  selectCategory,
} from "../../slices/dataSlice";
import { useSelector } from "react-redux";

const RenderedExpense = () => {

  const title = useSelector(selectTitle);
  const price = useSelector(selectPrice);
  const category = useSelector(selectCategory);

  const enteredData = {
    id: Math.random().toString(),
    title: title.disTitle,
    price: price.disPrice,
    category: category.disCategory,
  };

  const expense = enteredData;

    const [expenseItems, setExpenseItems] = useState([]);
    setExpenseItems([expense, ...expenseItems]);


  return (
    <View>
      {
        (title.disTitle,
        price.disPrice,
        category.disCategory ? <NewExpense /> : null)
      }
      {
        expenseItems.map(() => {
          <NewExpense key={enteredData.id} /> })
      }
    </View>
  );
};
Share Improve this question asked Sep 6, 2021 at 20:38 DhruvDhruv 11 gold badge1 silver badge4 bronze badges 1
  • 2 I think your infinite loop originates from here: const [expenseItems, setExpenseItems] = useState([]); setExpenseItems([expense, ...expenseItems]); – J_K Commented Sep 6, 2021 at 20:47
Add a ment  | 

2 Answers 2

Reset to default 6

Executing a setState triggers a re-render, so we should never have a setState inside the render method, or else an infitine loop happens.

Because you have the setExpenseItems([expense, ...expenseItems]); inside the render method, you will always get that exception.

You can put this part inside a useEffect that runs only when the values inside the brackets change, instead of every time the ponent renders:

    useEffect(() => {
        const enteredData = {
            id: Math.random().toString(),
            title: title.disTitle,
            price: price.disPrice,
            category: category.disCategory,
        };

        const expense = enteredData;

        setExpenseItems([expense, ...expenseItems]);
    }, [title, price, category]);

You're calling your setExpenseItems within your directly inside your ponent, this will cause your ponent to re-render infinitely because whenever state is set, the ponent is re-rendered. So, it'll just keep setting the state and re-redering.

If you want to set the state as soon as the ponent loads you should use the useEffect hook.

Like this:

import React, { useState, useEffect } from "react";

...

const title = useSelector(selectTitle);
const price = useSelector(selectPrice);
const category = useSelector(selectCategory);

const enteredData = {
    id: Math.random().toString(),
    title: title.disTitle,
    price: price.disPrice,
    category: category.disCategory,
  };

const expense = enteredData;

const [expenseItems, setExpenseItems] = useState([]);

useEffect(()=>{
    setExpenseItems([expense, ...expenseItems]);
},[])
...

Notice how I called setExpenseItems within useEffect. It'll call setExpenseItems only when the ponent is first rendered. useEffect also accepts a list of dependencies, which will determine if what ever is specified within the function will run. But I passed an empty array as my dependency.

See here, for more information.

本文标签: