Как обновить Api, не делая бесконечного цикла?

#javascript #reactjs

Вопрос:

Я хочу обновлять и отображать значение Api всякий раз, когда создается новый запрос на публикацию, без обновления страницы.
Вот в чем проблема, В моей реализации React hook, когда я вызываю API, это бесконечный вызов Api на сервер. Я просто хочу, чтобы он позвонил, когда будет добавлен новый запрос на публикацию.

Что я делаю не так и как это исправить?

 const [data, setData] = useState([]);

useEffect(() => {

        const fetchData = () => {
            fetch('http://127.0.0.1:8000/main/api/')
            .then(response => response.json())
            .then((res) => {
                const data = res.map((item, index) => ({
                    title: item.title,
                    price: item.price,
                    quantity: item.quantity,
                }));
                setData(data);
            });
        };

        console.log(data)
        fetchData();

    },[data]);
 

Полный Код App.js

 export default function OrderPreview(props) {

    const classes = useStyles();

    const [data, setData] = useState([]);
    useEffect(() => {

        const fetchData = () => {
            fetch('http://127.0.0.1:8000/main/api/')
            .then(response => response.json())
            .then((res) => {
                const data = res.map((item, index) => ({
                    title: item.title,
                    price: item.price,
                    quantity: item.quantity,
                }));
                setData(data);
            });
        };

        console.log(data)
        fetchData();

    },[data]);

    return (
        <main className={clsx(classes.content, {
                [classes.contentShift]: props.openstate, })}>
            <Grid container >
                <Grid item sm={12} >
                    <TableContainer className={classes.tableStyle}>
                        <Table>
                            <TableHead>
                                <TableRow>
                                    <TableCell align='center' >#</TableCell>
                                    <TableCell style={{paddingLeft:'90px'}} >Name</TableCell>
                                    <TableCell align='center' >Quantity</TableCell>
                                    <TableCell align='center' >Price</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody >
                                {data.map((item, index) => (
                                    <TableRow key={index}>
                                        <TableCell align='center' >{index   1}</TableCell>
                                        <TableCell style={{paddingLeft:'90px'}} >{item.title}</TableCell>
                                        <TableCell align='center' >{item.quantity}</TableCell>
                                        <TableCell align='center' >$ {item.price * item.quantity}</TableCell>
                                    </TableRow>


                                ))}
                                <TableCell colSpan={3} align='right' style={{paddingRight:'20px'}}> Total Price</TableCell>
                                <TableCell align='center' > non </TableCell>
                            </TableBody>
                        </Table>
                    </TableContainer>
                </Grid>
            </Grid>
        </main>
    );


}
 

Ответ №1:

Если вы не хотите продолжать извлекать API, просто удалите data его в массиве зависимостей.

У вас setData(data); внутри useEffect , так что он будет просто продолжать повторять рендеринг снова useEffect и setData(data) снова .

 useEffect(() => {
  const fetchData = () => {
    fetch("http://127.0.0.1:8000/main/api/")
      .then((response) => response.json())
      .then((res) => {
        const data = res.map((item, index) => ({
          title: item.title,
          price: item.price,
          quantity: item.quantity,
        }));
        setData(data);
      });
  };

  console.log(data);
  fetchData();
}, []); // <-- REMOVE DATA HERE
 

Комментарии:

1. Но тогда страница не будет повторно отображаться при выполнении нового запроса на публикацию без обновления страницы.

2. Что вы имеете в виду под new POST request этим ? И откуда это берется?

3. Я создаю запрос на публикацию в API, содержащий сведения о новых элементах, затем я хочу, чтобы он отображал все детали, не обновляя страницу. Это похоже на систему оформления покупок в магазине, чтобы дать вам представление.

4. Понятно, значит, новый предмет, вероятно, в твоем реквизите, верно?

5. Мне нужно было бы увидеть больше кода, чтобы быть конкретным, но один из способов обойти эту проблему-создать крючок const [rerender, setRerender] = useState(false); в том же компоненте, что и с useEffect и fetch . Затем добавьте rerender в массив зависимостей useEffect и добавьте setRerender(!rerender) в обработчик событий, который изменяет данные (не выборку!), скорее всего, onClick для добавления элементов.