Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useReducer init as props

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>
    );
}
like image 537
i like Cola Avatar asked Nov 21 '25 12:11

i like Cola


1 Answers

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.

like image 138
Giorgi Moniava Avatar answered Nov 23 '25 00:11

Giorgi Moniava