reactjs 未捕获的类型错误:在我的React项目中,对象不可迭代(无法读取属性Symbol(Symbol.iterator))

9jyewag0  于 2023-06-05  发布在  React
关注(0)|答案(4)|浏览(347)

我是上下文API的新手,并试图让我的代码工作。我收到错误:
未捕获的类型错误:对象不可迭代(无法读取属性Symbol(Symbol.iterator))
你们这些好人能帮我吗?
initialUserState记录一个对象,看起来像这样:{name:nanny}
我的上下文文件是:

import { createContext, useState } from "react";

const initialUserState = JSON.parse(localStorage.getItem("user"));
console.log(initialUserState);
const initialFormValues = {
  video: "Video.mp4",
  hourly: "",
  ageRange: [],
  car: "",
  languages: [],
  homework: "",
  license: "",
  preference: "",
  vaccination: "",
  radius: "",
  booked: "",
  fileUpload: "file.jpg",
};

export const Global = createContext();

export default function GlobalContext({ children }) {
  const [state, setState] = useState(initialUserState);
  const [values, setValues] = useState(initialFormValues); //setting form state
  const [radioSelected, setRadioSelected] = useState();

  const changeState = (newState = {}) => {
    const tempState = { ...state, ...newState };
    setState(tempState);
    localStorage.setItem("user", JSON.stringify(tempState));
  };

  return (
    <Global.Provider
      value={[
        { ...state },
        changeState,
        values,
        setValues,
        radioSelected,
        setRadioSelected,
      ]}
    >
      {children}
    </Global.Provider>
  );
}

然后在我获取状态的地方,initialFormValues不会在控制台中登录:

const HourlyRate = () => {

  //context API

  const [values, setValues] = useContext(GlobalContext); **//this is where the error is being flagged from**

  //handle form value changes
  const handleChange = (e) => {
    e.preventDefault();

    const { name, value } = e.target;
    setValues({ ...values, [name]: value });
  };

  return (
    <div className="sub-settings-div">
      <Link className="back" to="/video-upload">
        <span>
          <ArrowBackIcon />
        </span>
        Back
      </Link>
      <h3 className="sub-settings-header">{t("common.title")}</h3>
      <h2 className="sub-settings-sub-header">{t("hourly.subTitle")}</h2>
      <p className="range">(10.45 &euro; - 20 &euro;) </p>
      <form className="input">
        <TextField
          className="input-field"
          required
          id="outlined-required"
          label="Hourly Rate"
          name="hourly"
          value={values.hourly}
          onChange={handleChange}
        />
      </form>
      <div className="nav-btns">
        <Link to="/video-upload" className="prev-link">
          <button className="prev">{t("buttons.back")}</button>
        </Link>
        <Link to="/age-range" className="next-link">
          <button className="next">
            {t("buttons.next")}
            <span>
              <ArrowForwardIcon />
            </span>
          </button>
        </Link>
      </div>
    </div>
  );
};

export default HourlyRate;
mqxuamgl

mqxuamgl1#

如果你正在编写自己的React钩子(use...函数),那么这可能会根据你在自定义钩子中返回值的方式而发生。
例如,返回一个数组需要一个数组:

const [count, setCount, increment] = useCount()
// useCount should return:
return [count, setCount, increment]

同样,返回一个对象需要一个对象:

const {count, setCount, increment} = useCount()
// useCount should return:
return {count, setCount, increment}

两者的任何混合都会导致以下错误:

Uncaught TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))

例如:

const [count, setCount, increment] = useCount()
// useCount will error if it returns:
return {count, setCount, increment}
um6iljoc

um6iljoc2#

我看到的几个问题:
1.您正在将上下文提供程序组件GlobalContext传递给useContext钩子const [values, setValues] = useContext(GlobalContext);
1.上下文值是一个数组,因此当使用数组解构时,数组元素的顺序很重要。
为上下文使用正确的变量。您可能希望将上下文命名为GlobalContext,并将提供程序重命名为类似GlobalProvider的名称。我还建议为上下文值使用一个对象,以消除数组元素顺序破坏问题。

export const GlobalContext = createContext();

export default function GlobalProvider({ children }) {
  const [state, setState] = useState(initialUserState);
  const [values, setValues] = useState(initialFormValues); //setting form state
  const [radioSelected, setRadioSelected] = useState();

  const changeState = (newState = {}) => {
    const tempState = { ...state, ...newState };
    setState(tempState);
    localStorage.setItem("user", JSON.stringify(tempState));
  };

  return (
    <Global.Provider
      value={{
        state,
        changeState,
        values,
        setValues,
        radioSelected,
        setRadioSelected,
      }}
    >
      {children}
    </Global.Provider>
  );
}

然后假设主App组件正确地 Package 在GlobalProvider中,使用钩子中的对象解构。

const { values, setValues } = useContext(GlobalContext);
mbskvtky

mbskvtky3#

你的价值是:

[
    { ...state },
    changeState,
    values,
    setValues,
    radioSelected,
    setRadioSelected,
  ]

这一行:const [values, setValues] = useContext(GlobalContext);将解构值(数组),但解构数组和对象之间有一个关键区别:对于数组,解构是按顺序的(不像对象是按名称的),这意味着:values变量将保存第一个对象{ ...state },它是不可迭代的
如果你的值是一个对象:

{
    state,
    changeState,
    values,
    setValues,
    radioSelected,
    setRadioSelected,
  }

useContext将为const {state,setValues} = useContext(GlobalContext);

cu6pst1q

cu6pst1q4#

我遇到了这个令人困惑的错误消息时,试图传播一个值,是意外未定义。例如

let abc = undefined
let def = [...abc]

相关问题