2

Im new to react and im trying to make a little project and ran into react context because i find it annoying passing down the props. I'm running into a problem with the useContext() hook.

My Context file

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

}

And I'm trying to save the object from the context into this one like so:

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

I'm importing the Context like this:

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

The error says the object is not iterable so I assume that i declare somewhere that board is an array? If that is so where exactly and how can I fix the error?

Thanks for everyone helping in advance:)

3
  • There is something that you dont showing us as this code looks ok, try making an example in sandbox like codesandbox.io/s/new?utm_source=dotnew Commented Nov 20, 2020 at 11:53
  • Show us how you use board the error might be from board.map or something which is an error because board is an object. Commented Nov 20, 2020 at 11:55
  • No im not using any map method. The only thing i wanna do in BoardName is to store data from the form into the context. I put my whole project into (codesandbox.io/s/modern-meadow-0pklj) sandbox so that you can see what I wanna do. Commented Nov 20, 2020 at 12:47

3 Answers 3

3

Iterable Objects and regular objects in javascript are two different concepts.

According to the MDN web doc, Regular objects in javascript are a collection of properties and a property is an association between a name (or key) and a value. Value can be a function or any literal value.

Iterable objects are any object that contains the [Symbol.iterator] function. I'll give you an example of an Iterable object.

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

To make object iterable we need to use [Symbol.iterator] but it will only work with array-like objects. Array-likes are objects that have indexes and length, so they look like arrays.

Tip: Arrays are built-in Iterable object

Now coming to your concern, you are using the array (or tuple) for destructuring the regular object literal. That's the reason you are getting the error as 'object is not iterable'. You need to have an iterable object for that when you are using an array (or tuple).

You can solve this problem in two ways. First, you can convert your object to an iterable object or the best solution that I will recommend is that you can use the object to destructure the regular object.

So, your code will look like this.

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

Default Value would be JSON object in order to add data to it.

Use your context like this.

const { board, setBoard }  = useContext(BoardContext);
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you that solved that error. But now im getting an error that says that board is undefined as if the board from context is not correctly saved into the object of the other class. Any idea why?
Check you BoardContext. Your BoardContext must have empty object. export const BoardContext = React.createContext({})
The board stays undefined when printing it.
Apologize!!! check the edited code default value must be JSON object
3

This error can be caused passing in the value to the provider incorrectly. Check the braces and brackets are correct:

Incorrect:

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

Correct:

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

Comments

1

I got behind some tutorials again and found my mistake. I had my .Provider tag in the wrong file. It's supposed to be in the App where the Router is, where you call all the components so they all have access to the context.

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;

Here's my router function, where im passing the context to the components to BoardName, TimePeriod and PhaseForm.

Thanks for everyone helping me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.