2

Why is there an error here:

Objects are not valid as a React child (found: object with keys {count}). If you meant to render a collection of children, use an array instead.

If you do not use prop init there is no error

import { useReducer } from "react";

function init(initialCount) {
    return { count: initialCount };
}

function reducer(state, action) {
    switch (action.type) {
        case "increment":
            return { count: +state.count + 1 };
        case "decrement":
            return { count: +state.count - 1 };
        case "reset":
            return init(action.payload);
        default:
            throw new Error();
    }
}

function Counter({reducer, initialCount, init}) {
    const [state, dispatch] = useReducer(reducer, initialCount, init);
    return (
        <>
            Count: {state.count}
            <button
                onClick={() =>
                    dispatch({ type: "reset", payload: initialCount })
                }
            >
                {" "}
                Reset
            </button>
            <button onClick={() => dispatch({ type: "decrement" })}>-</button>
            <button onClick={() => dispatch({ type: "increment" })}>+</button>
        </>
    );
}

export default function App() {
    return (
        <div className="App">
            {/* <Counter reducer={reducer} initialCount={{count: 0}} /> */}
            <Counter reducer={reducer} initialCount={{count: 0}} init={init} />          
        </div>
    );
}
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
i like Cola
  • 277
  • 6
  • 15

1 Answers1

2

In such situation:

  const [state, dispatch] = useReducer(reducer, initialArg, init);

The docs say:

You can also create the initial state lazily. To do this, you can pass an init function as the third argument. The initial state will be set to init(initialArg).

in your case initialArg is same as initialCount which is an object, hence it will call below function with object as argument:

function init(initialCount) {
    return { count: initialCount };
}

and it will return object, where count refers to an object too. And then you are trying to render an object, and react complains.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
  • Thank you for answer, but i not render an object, i extract count in reducer. Function init only for initializing. IYou can uncomment commented string and remove argument init from counter and remain useReducer(reducer, initialCount, init). the example will work fine – i like Cola Jan 20 '22 at 19:15
  • 1
    @ilikeCola read the answer carefully or `console.log(state.count)` to see that it is an object. – Giorgi Moniava Jan 20 '22 at 19:20
  • 1
    **giorgi moniava** Thank you, yes you were right I looked at my code inattentively for my second case – i like Cola Jan 20 '22 at 19:28