React Native报错:undefined is not an object (evaluating 'getStandardUnit.findIndex')
React Native AddFood组件错误:undefined is not an object (evaluating 'getStandardUnit.findIndex')
开发AddFood组件时触发错误:undefined is not an object (evaluating 'getStandardUnit.findIndex'),错误出现在计算index的代码行和渲染{getStandardUnit[index].standardUnit}的行。已尝试将getStandardUnit初始状态从[]改为initialState,移除API调用外层的async函数,但问题仍存在。
以下是原代码:
const AddFood = (props) => { // DROPDOWN MENU CONST (1 - for dropdown menu, 2 - for API call, 3 - for getting the standard unit) const [getSelected, setSelected] = React.useState(""); const [ingredientData, setData] = React.useState([]); const [getStandardUnit, setStandardUnit] = React.useState(initialState); const initialState = [ {key: "", standardUnit: ""}, ] // QUANTITY CONST const [getQuantity, setQuantity] = React.useState(""); // DATE CONST const [getDay, setDay] = React.useState(""); const [getMonth, setMonth] = React.useState(""); const [getYear, setYear] = React.useState(""); // DROPDOWN MENU DATA React.useEffect(() => { //(async () => { try { fetch('http://localhost:3000/api/ingredients', { method: 'GET', mode: 'cors', headers: { 'Accept': 'application/json', }, }) .then(response => response.json()) .then((responseJson) => { //console.log('getting data from fetch (dropdown)') //console.log(responseJson) // Store values in temporary array (newArray) let newArray = responseJson.map((item) => { return {key: item.ingredientID, value: item.name} }) let newArraySU = responseJson.map((item) => { return {key: item.ingredientID, standardUnit: item.standardUnit} }) // Set data variable setStandardUnit(newArraySU) setData(newArray) }) } catch (error) { console.log(error) } //}) },[]) const dayData = [ {key:'1',value:'01'}, ] const monthData = [ {key:'1',value:'01'}, ] const yearData = [ {key:'2023',value:'2023'}, ] const onPressBack = () => { props.navigation.navigate('BarcodeOrManual'); } const concatDate = getDay + getMonth + getYear // ASYNC COMPONENT TO POST DATA TO API const storeData = async () => { try { await fetch('http://localhost:3000/api/pantry', { method: 'POST', headers: { 'Accept': '*/*', 'Content-Type': 'application/json', }, body: JSON.stringify({ ingredientID: {getSelected}, quantity: {getQuantity}, dateExpiry: {concatDate}, frozen: 1 }) }) .then(response => response.json()) .then(responseJson => console.log(responseJson)) } catch (error) { console.log(error) } } // VALIDATION AND PASS DATA TO DATABASE const showAlert = () => { if (getSelected && getQuantity && getDay && getMonth && getYear) { Alert.alert ( "Food entered successfully" ); storeData(); } else { Alert.alert ( "Please fill in all the fields" ); } } var index = getStandardUnit.findIndex(function(item) { return item.key == getSelected }); return ( <View style={{ paddingHorizontal: 20, paddingVertical: 50, flex: 1, justifyContent: 'center' }}> {/* DROPDOWN MENU FOR FOOD */} <SelectList data={ingredientData} // onSelect={() => alert(selected)} // setSelected={setSelected} setSelected={setSelected} dropdownItemStyles={{marginHorizontal:10}} dropdownTextStyles={{color:'black'}} searchPlaceholder="Enter item" placeholder="Enter item" maxHeight={100} /> {/* FOOD QUANTITY */} <Text style={{ marginTop: 9, marginBottom: 3, fontWeight: 'bold' }}>Quantity:</Text> <View style={{ flexDirection: "row" }}> <TextInput style={styles.input} onChangeText={setQuantity} value={getQuantity} keyboardType="numeric" /> <Text>{index}</Text> <Text style={{ marginTop: 15 }}>{getStandardUnit[index].standardUnit}</Text> </View> </View> ) }
问题分析与修复步骤
初始状态定义顺序错误
调用React.useState(initialState)时,initialState还未定义(const无变量提升),导致getStandardUnit初始值为undefined,调用findIndex直接报错。修复:将
initialState移到useState之前:const initialState = [ {key: "", standardUnit: ""}, ] const [getStandardUnit, setStandardUnit] = React.useState(initialState);处理
findIndex返回-1的情况
当getSelected为空或无匹配项时,findIndex返回-1,此时getStandardUnit[-1]为undefined,访问.standardUnit会触发新错误。修复:添加判断逻辑避免无效索引访问:
const index = getStandardUnit.findIndex(item => item.key == getSelected); const standardUnit = index !== -1 ? getStandardUnit[index].standardUnit : ""; // 渲染时替换为变量 <Text style={{ marginTop: 15 }}>{standardUnit}</Text>Fetch错误处理不完善
原try/catch无法捕获HTTP错误(如404、500),fetch仅在网络故障时抛出异常。修复:在
then中检查响应状态:fetch('http://localhost:3000/api/ingredients', { ... }) .then(response => { if (!response.ok) throw new Error(`HTTP status: ${response.status}`); return response.json(); }) .then((responseJson) => { // 数据处理逻辑 }) .catch(error => console.log(error));POST请求数据格式冗余
JSON.stringify中的{getSelected}可简化为直接传值,避免不必要的嵌套:body: JSON.stringify({ ingredientID: getSelected, quantity: getQuantity, dateExpiry: concatDate, frozen: 1 })
修复后的核心代码片段
const AddFood = (props) => { const initialState = [ {key: "", standardUnit: ""}, ] const [getSelected, setSelected] = React.useState(""); const [ingredientData, setData] = React.useState([]); const [getStandardUnit, setStandardUnit] = React.useState(initialState); // ...其他状态定义 React.useEffect(() => { fetch('http://localhost:3000/api/ingredients', { method: 'GET', mode: 'cors', headers: { 'Accept': 'application/json', }, }) .then(response => { if (!response.ok) throw new Error(`HTTP status: ${response.status}`); return response.json(); }) .then((responseJson) => { let newArray = responseJson.map((item) => ({ key: item.ingredientID, value: item.name })) let newArraySU = responseJson.map((item) => ({ key: item.ingredientID, standardUnit: item.standardUnit })) setStandardUnit(newArraySU) setData(newArray) }) .catch(error => console.log(error)) },[]) // ...其他函数定义 const index = getStandardUnit.findIndex(item => item.key == getSelected); const standardUnit = index !== -1 ? getStandardUnit[index].standardUnit : ""; return ( // ...其他渲染内容 <View style={{ flexDirection: "row" }}> <TextInput style={styles.input} onChangeText={setQuantity} value={getQuantity} keyboardType="numeric" /> <Text>{index}</Text> <Text style={{ marginTop: 15 }}>{standardUnit}</Text> </View> // ...其他渲染内容 ) }
内容的提问来源于stack exchange,提问作者Hercules' Creed
相关产品推荐
相关产品推荐

