首页 > 解决方案 > React hooks 应用程序适用于以下静态数据,但在迭代真实数据时出错

问题描述

React hooks 应用程序可以很好地处理以下传递到下拉选择框中的静态选项数据。但是在集成到后端并迭代数据时,它会抛出错误Cannot read property 'name' of undefined错误。有人可以请教可能是什么问题。

const options = [
    { name: 'Aaaan', email:"aaan@test.com", id: 1},
    { name: 'Baaa', email:"baaa@test.com", id: 2},
    { name: 'Crooo', email:"crooo@test.com", id: 3},
    { name: 'Daaa', email:"daaa@test.com", id: 4}
  ];


TypeError: Cannot read property 'name' of undefined
(anonymous function)
C:/project/work/devchoice/src/components/nominatePerson.js:121
  118 | <div key={i}>
  119 |     <div className="row eachrecord">
  120 |     <div className="column" >
> 121 |         <label className="nomlabel">{x[i].name} <b>>></b></label>
      | ^  122 |     </div>
  123 |     <input
  124 |         required type='textarea'
View compiled
NominatePerson
C:/project/work/devchoice/src/components/nominatePerson.js:116
  113 | </div>
  114 | <form onSubmit={handleSubmit(sendNomination)}>
  115 | <div className="nomineesSelectedList">
> 116 |     <h4>Selected Nominees</h4>
      | ^  117 |     {manageNominees.map((x, i) =>
  118 |         <div key={i}>
  119 |             <div className="row eachrecord">

NominatePerson.js

const NominatePerson = () => {

    const maxOptions = 3;
    const [manageNominees, setManageNominees] = useState([]);
    const [nomRegister, setNomRegister] = useState([]);
    const { register, handleSubmit, watch, formState: { errors }, reset} = useForm();


    useEffect(() => {
        const fetchData = async () => {
            // const email = localStorage.getItem("loginEmail");
            try {
                const res = await Axios.get('http://localhost:8000/service/nomineeslist');
                setManageNominees(res.data);
                console.log("Get the list of nominees :" + res.data);
            } catch (e) {
                console.log(e);
            }
        }
        fetchData();
    }, []);


    const handleTypeSelect = (e) => {
        const copy = [...manageNominees];
        copy.push(e);
        setManageNominees(copy);
    };

    const handleTypeRemove = (e) => {
        const copy = [...manageNominees];
        let index = copy.indexOf(e);
        copy.splice(index, 1);
        setManageNominees(copy);
        const updateList = nomRegister.map((item) => {
            return { ...item };
        });
        //delete the specific array case depends on the id
        updateList.splice(index, 1);
        setNomRegister(updateList);
    };

    const sendNomination = () => {
        console.log("Arry has: "+JSON.stringify(nomRegister));
    };

    manageNominees.forEach(option=>{
        option.displayValue=option.name+"\t"+option.email;
    })

    const handleChange = (e, i) => {
        const { name, email, value } = e.target;
        const updateList = nomRegister.map((item) => {
            return { ...item };
        });

        const emailList = selectedOption.map((x, j) => {
           return x[j].email;
        });
        //change the specific array case depends on the id
        updateList[i] = { ...updateList[i], name: name, email:emailList[i], reason: value };
        setNomRegister(updateList);
    };
  
    return (
        <div className="App">
            <div className="navbar-nav">
                <div className="leftNavItem">
                    <a><Link to={'/dashboard'} className="nav-link"> <b>Dashboard</b> </Link></a>
                </div>
            </div>
            <h1>Nominate a person</h1>
            <div className="nomineeSelectBox">
                <div id="dialog2" className="triangle_down1"/>
                <div className="arrowdown">
                    <Multiselect
                        onSelect={handleTypeSelect}
                        onRemove={handleTypeRemove}
                        options={manageNominees.length + 1 === maxOptions ? [] : manageNominees}
                        displayValue="displayValue"
                        showCheckbox={true}
                        emptyRecordMsg={"Maximum nominees selected !"}
                    />

                </div>
            </div>
            <div className="nominationcount">
            </div>
            <form onSubmit={handleSubmit(sendNomination)}>
            <div className="nomineesSelectedList">
                <h4>Selected Nominees</h4>
                {manageNominees.map((x, i) =>
                    <div key={i}>
                        <div className="row eachrecord">
                        <div className="column" >
                            <label className="nomlabel">{x[i].name} <b>>></b></label>
                        </div>
                        <input
                            required type='textarea'
                            placeholder="Please provide reason for nomination.."
                            key={i}
                            id={i}
                            name={x[i].name}
                            className='nomineechoosed'
                            onChange={(e) => handleChange(e, i)}
                        />
                        </div>
                    </div>
                )}
                <div className="row">
                    <div className="buttongroup">
                        <input id="Submit" type="submit" value="Submit"/>
                        <input id="Cancel" type="button" value="Cancel"/>
                    </div>

                </div>
            </div>
            </form>
        </div>
    )
}
export default NominatePerson

在此处输入图像描述

标签: reactjsaxiosreact-hooks

解决方案


x在回调函数中map是对象。 manageNominees.map((x, i) =>{console.log(x)});将为您打印完整的对象。

请参阅array.map的文档。

现在您看到的错误是因为namex. 所以你应该尝试设置{x?.name}.

编辑:正如 Ala Hamadi 在评论中提到的,?.可选链接有助于检查嵌套对象上是否存在属性/键。

请参阅文档以获取可选链接运算符 (?.)


推荐阅读