Reactjs 装载时运行的useEffect导致错误和空白对象

Reactjs 装载时运行的useEffect导致错误和空白对象,reactjs,react-hooks,Reactjs,React Hooks,第一次单击“添加”时,我会得到一个空白的虚拟现实项目,然后在第二次单击后,相应的项目将显示出来。如果我添加一个新的URL并第三次单击,则该项目将在第四次单击之前不会显示。我的useffect和状态值很可能有问题 import React,{useState,useffect}来自“React”; 从'@material ui/core/styles'导入{makeStyles}; 从“@material ui/core/List”导入列表; 从“@material ui/core/Divider

第一次单击“添加”时,我会得到一个空白的虚拟现实项目,然后在第二次单击后,相应的项目将显示出来。如果我添加一个新的URL并第三次单击,则该项目将在第四次单击之前不会显示。我的
useffect
和状态值很可能有问题

import React,{useState,useffect}来自“React”;
从'@material ui/core/styles'导入{makeStyles};
从“@material ui/core/List”导入列表;
从“@material ui/core/Divider”导入分隔器;
从“./AvatarListItem”导入AvatarListItem;
从“@material ui/icons/Add”导入AddIcon;
从“@material ui/core/TextField”导入TextField;
从“@material ui/core/Button”导入按钮;
从“axios”导入axios;
const useStyles=makeStyles((主题)=>({
根目录:{
显示:“flex”,
justifyContent:'之间的空间',
flexDirection:'列',
flexWrap:“wrap”,
背景色:theme.palete.background.paper,
},
内联:{
显示:“内联”,
},
表单控制:{
宽度:“100%”,
边距:主题。间距(1),
marginBottom:'50px',
最小宽度:120,
},
扩展图标:{
保证金:“10px”,
边缘光:主题。间距(1),
},
}));
导出默认函数AvatarList(){
const classes=useStyles();
const[url,setUrl]=useState(“”);
const[itemDetails,setItemDetails]=useState({});
const[items,setItems]=useState([]);
const[search,setSearch]=useState(“”);
useffect(()=>{
const fetchData=async()=>{
常量结果=等待axios(
`http://127.0.0.1:5000/api/resources/products?url=${url}`,
)
setItemDetails(结果数据[0]);
}
fetchData()
},[搜索])
const addItem=(itemDetails)=>{
const newItems=[…项,项详细信息];
设置项目(新项目);
};
让handleSubmit=(e)=>{
e、 预防默认值();
控制台日志(itemDetails);
附件(项目详情);
};
let removeItem=(索引)=>{
const newItems=[…items];
新项目.拼接(索引,1);
设置项目(新项目);
};
返回(
handleSubmit(e)}>
setUrl(e.target.value)}value={url}/>
设置搜索(url)}>
{items.map((项,索引)=>(
))}
);
}

更好的方法可能是完全依赖于
onSubmit
回调,而不是依赖于useffect,因为useffect的运行频率可能超过需要。此外,看起来根本不需要使用
搜索
项目详细信息
状态

import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import Divider from '@material-ui/core/Divider';
import AvatarListItem from './AvatarListItem';
import AddIcon from '@material-ui/icons/Add';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import axios from 'axios';

const useStyles = makeStyles((theme) => ({
    root: {
        display: 'flex',
        justifyContent: 'space-between',
        flexDirection: 'column',
        flexWrap: 'wrap',
        backgroundColor: theme.palette.background.paper,
    },

    inline: {
        display: 'inline',
    },
    formControl: {
        width: '100%',
        margin: theme.spacing(1),
        marginBottom: '50px',
        minWidth: 120,
    },
    extendedIcon: {
        margin: '10px',
        marginRight: theme.spacing(1),
    },
}));

export default function AvatarList() {
    const classes = useStyles();
    const [url, setUrl] = useState('');
    const [items, setItems] = useState([]);


    const addItem = (itemDetails) => {
        const newItems = [...items, itemDetails];
        setItems(newItems);
    };

    let handleSubmit = async (e) => {
        e.preventDefault();
        const result = await axios(
            `http://127.0.0.1:5000/api/resources/products?url=${url}`,
        )
        addItem(result.data[0]);
    };

    let removeItem = (index) => {
        const newItems = [...items];
        newItems.splice(index, 1);
        setItems(newItems);
    };

    return (
        <div>
            <form className={classes.formControl} onSubmit={handleSubmit}>
                <TextField id="outlined-basic" label="Amazon Url" variant="outlined" name='newItem' onChange={e => setUrl(e.target.value)} value={url} />
                <Button variant="contained" color="primary" type="submit">
                    <AddIcon className={classes.extendedIcon} />
                </Button>
            </form>


            <List className={classes.root}>
                {items.map((item, index) => (
                    <React.Fragment key={index}>
                        <AvatarListItem
                            itemDetails={item}
                            key={index}
                            index={index}
                            removeItem={removeItem}
                        />
                        <Divider variant="middle" component="li" />
                    </React.Fragment>
                ))}
            </List>
        </div >
    );
}
import React,{useState,useffect}来自“React”;
从'@material ui/core/styles'导入{makeStyles};
从“@material ui/core/List”导入列表;
从“@material ui/core/Divider”导入分隔器;
从“./AvatarListItem”导入AvatarListItem;
从“@material ui/icons/Add”导入AddIcon;
从“@material ui/core/TextField”导入TextField;
从“@material ui/core/Button”导入按钮;
从“axios”导入axios;
const useStyles=makeStyles((主题)=>({
根目录:{
显示:“flex”,
justifyContent:'之间的空间',
flexDirection:'列',
flexWrap:“wrap”,
背景色:theme.palete.background.paper,
},
内联:{
显示:“内联”,
},
表单控制:{
宽度:“100%”,
边距:主题。间距(1),
marginBottom:'50px',
最小宽度:120,
},
扩展图标:{
保证金:“10px”,
边缘光:主题。间距(1),
},
}));
导出默认函数AvatarList(){
const classes=useStyles();
const[url,setUrl]=useState(“”);
const[items,setItems]=useState([]);
const addItem=(itemDetails)=>{
const newItems=[…项,项详细信息];
设置项目(新项目);
};
让handleSubmit=async(e)=>{
e、 预防默认值();
常量结果=等待axios(
`http://127.0.0.1:5000/api/resources/products?url=${url}`,
)
addItem(结果数据[0]);
};
let removeItem=(索引)=>{
const newItems=[…items];
新项目.拼接(索引,1);
设置项目(新项目);
};
返回(
setUrl(e.target.value)}value={url}/>
{items.map((项,索引)=>(
))}
);
}

更好的方法可能是完全依赖于
onSubmit
回调,而不是依赖于useffect,因为useffect的运行频率可能超过需要。此外,看起来根本不需要使用
搜索
项目详细信息
状态

import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import Divider from '@material-ui/core/Divider';
import AvatarListItem from './AvatarListItem';
import AddIcon from '@material-ui/icons/Add';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import axios from 'axios';

const useStyles = makeStyles((theme) => ({
    root: {
        display: 'flex',
        justifyContent: 'space-between',
        flexDirection: 'column',
        flexWrap: 'wrap',
        backgroundColor: theme.palette.background.paper,
    },

    inline: {
        display: 'inline',
    },
    formControl: {
        width: '100%',
        margin: theme.spacing(1),
        marginBottom: '50px',
        minWidth: 120,
    },
    extendedIcon: {
        margin: '10px',
        marginRight: theme.spacing(1),
    },
}));

export default function AvatarList() {
    const classes = useStyles();
    const [url, setUrl] = useState('');
    const [items, setItems] = useState([]);


    const addItem = (itemDetails) => {
        const newItems = [...items, itemDetails];
        setItems(newItems);
    };

    let handleSubmit = async (e) => {
        e.preventDefault();
        const result = await axios(
            `http://127.0.0.1:5000/api/resources/products?url=${url}`,
        )
        addItem(result.data[0]);
    };

    let removeItem = (index) => {
        const newItems = [...items];
        newItems.splice(index, 1);
        setItems(newItems);
    };

    return (
        <div>
            <form className={classes.formControl} onSubmit={handleSubmit}>
                <TextField id="outlined-basic" label="Amazon Url" variant="outlined" name='newItem' onChange={e => setUrl(e.target.value)} value={url} />
                <Button variant="contained" color="primary" type="submit">
                    <AddIcon className={classes.extendedIcon} />
                </Button>
            </form>


            <List className={classes.root}>
                {items.map((item, index) => (
                    <React.Fragment key={index}>
                        <AvatarListItem
                            itemDetails={item}
                            key={index}
                            index={index}
                            removeItem={removeItem}
                        />
                        <Divider variant="middle" component="li" />
                    </React.Fragment>
                ))}
            </List>
        </div >
    );
}
import React,{useState,useffect}来自“React”;
从'@material ui/core/styles'导入{makeStyles};
从“@material ui/core/List”导入列表;
从“@material ui/core/Divider”导入分隔器;
从“./AvatarListItem”导入AvatarListItem;
从“@material ui/icons/Add”导入AddIcon;
从“@material ui/core/TextField”导入TextField;
从“@material ui/core/Button”导入按钮;
从“axios”导入axios;
const useStyles=makeStyles((主题)=>({
根目录:{
显示:“flex”,
justifyContent:'之间的空间',
flexDirection:'列',
flexWrap:“wrap”,
背景色:theme.palete.background.paper,
},
内联:{
显示:“内联”,
},
表单控制:{
宽度:“100%”,
边距:主题。间距(1),
玛格