You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
  )

}

问题分析与修复步骤

  1. 初始状态定义顺序错误
    调用React.useState(initialState)时,initialState还未定义(const无变量提升),导致getStandardUnit初始值为undefined,调用findIndex直接报错。

    修复:将initialState移到useState之前:

    const initialState = [
      {key: "", standardUnit: ""},
    ]
    const [getStandardUnit, setStandardUnit] = React.useState(initialState);
    
  2. 处理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>
    
  3. 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));
    
  4. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:47:07