【问题标题】:TypeError: Object is not iterable when working with react contextTypeError:使用反应上下文时对象不可迭代
【发布时间】:2021-03-03 19:47:09
【问题描述】:

我是 react 新手,我正在尝试制作一个小项目并遇到 react 上下文,因为我发现传递道具很烦人。我遇到了useContext() 挂钩的问题。

我的上下文文件

export function BoardProvider(props){

const [ board, setBoard ] = useState({
    id: null,
    name:  null,
    longterm: false,
    code: null,
    teacher: null,
    periodStart: null,
    periodEnd: null,
    totalDuration: null,
    phases: [],
    students: []

})
return (
    <BoardContext.Provider value={[board, setBoard]}>
        {props.children}
    </BoardContext.Provider>
)

}

我正在尝试将对象从上下文中保存到这个对象中,如下所示:

const [ board, setBoard ]  = useContext(BoardContext);

我正在像这样导入上下文:

import { BoardProvider } from '../../contexts/BoardContext'

错误表明对象不可迭代,所以我假设我在某处声明 board 是一个数组?如果是这样,究竟在哪里以及如何修复the error

感谢大家提前帮助:)

【问题讨论】:

  • 由于这段代码看起来没问题,所以您没有向我们展示某些内容,请尝试在沙盒中创建一个示例,例如 codesandbox.io/s/new?utm_source=dotnew
  • 告诉我们你是如何使用board
  • 不,我没有使用任何地图方法。我在 BoardName 中唯一想做的就是将表单中的数据存储到上下文中。我将整个项目放入 (codesandbox.io/s/modern-meadow-0pklj) 沙箱中,以便您可以看到我想做什么。

标签: reactjs react-context


【解决方案1】:

javascript中的可迭代对象和常规对象是两个不同的概念。

根据 MDN 网络文档,javascript 中的常规对象是属性的集合,而属性是名称(或键)与值之间的关联。值可以是函数或任何文字值。

可迭代对象是包含[Symbol.iterator] 函数的任何对象。我会给你一个 Iterable 对象的例子。

let iterableObject = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
    [Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (var item of iterableObject) {
    console.log(item); 
}

为了使对象可迭代,我们需要使用[Symbol.iterator],但它只适用于类似数组的对象。类数组是具有索引和长度的对象,因此它们看起来像数组。

提示:数组是内置的可迭代对象

现在引起您的关注,您正在使用数组(或元组)来解构常规对象字面量。这就是您收到“对象不可迭代”错误的原因。当您使用数组(或元组)时,您需要有一个可迭代的对象。

您可以通过两种方式解决此问题。首先,您可以将对象转换为可迭代对象,或者我推荐的最佳解决方案是您可以使用该对象来解构常规对象。

因此,您的代码将如下所示。

export function BoardProvider(props){

let defaultValue = {
  boards : [{
    id: null,
    name:  null,
    longterm: false,
    code: null,
    teacher: null,
    periodStart: null,
    periodEnd: null,
    totalDuration: null,
    phases: [],
    students: []
  }]
}
const [ board, setBoard ]= useState(defaultValue)

return (
    <BoardContext.Provider value={{board, setBoard}}>
        {props.children}
    </BoardContext.Provider>
)

默认值为 JSON 对象,以便向其添加数据。

像这样使用你的上下文。

const { board, setBoard }  = useContext(BoardContext);

【讨论】:

  • 感谢您解决了该错误。但是现在我收到一个错误,说板子未定义,就好像上下文中的板子没有正确保存到另一个类的对象中一样。知道为什么吗?
  • 检查您的 BoardContext。您的 BoardContext 必须有空对象。 export const BoardContext = React.createContext({})
  • 板在打印时保持未定义。
  • 道歉!!!检查编辑后的代码默认值必须是JSON对象
【解决方案2】:

我再次落后于一些教程并发现了我的错误。我的 .Provider 标记在错误的文件中。它应该在路由器所在的应用程序中,您可以在其中调用所有组件,以便它们都可以访问上下文。

function RouterApp() {

    const [ board, setBoard ] = useState(null);

    const value = useMemo(() => ({ board, setBoard}), [ board, setBoard])

    return (
        <Router>
            <div className="App">
                <BoardContext.Provider value={value}>
                    <Switch>
                        <Route path="/" exact component={BoardName} />
                        <Route path="/createboard/:name" exact component={TimePeriod} />
                        <Route path="/createboard:name/phases" exact component={PhaseForm} />
                    </Switch>
                </BoardContext.Provider>

            </div>
        </Router>
    );
}

export default RouterApp;

这是我的路由函数,我将上下文传递给 BoardName、TimePeriod 和 PhaseForm 的组件。

感谢大家帮助我。

【讨论】:

    【解决方案3】:

    此错误可能是由于将值错误地传递给提供程序而导致的。检查大括号和括号是否正确:

    不正确:

    <RegulatorContext.Provider value={{state, setState}}>
        <Regulator />
    </RegulatorContext.Provider>
    

    正确:

    <RegulatorContext.Provider value={[state, setState]}>
        <Regulator />
    </RegulatorContext.Provider>
    

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 2021-07-02
      • 1970-01-01
      • 2017-08-27
      • 2018-10-10
      相关资源
      最近更新 更多