This is usually called a functional component, not a hook component.
For the defaultProps you can do it like this:
const Body = ({ counter }) => {
return (
<div>
{counter}
</div>
);
}
Body.defaultProps = {
counter: 0
}
Answer from Arnaud Christ on Stack OverflowThis is usually called a functional component, not a hook component.
For the defaultProps you can do it like this:
const Body = ({ counter }) => {
return (
<div>
{counter}
</div>
);
}
Body.defaultProps = {
counter: 0
}
function Body({counter=0}) {
return (
<div>
body
</div>
);
}
counter now has initial value of 0
function Body({counter=0}) {
return (
<div>
body
</div>
);
}
counter now has initial value of 0
This is usually called a functional component, not a hook component.
For the defaultProps you can do it like this:
const Body = ({ counter }) => {
return (
<div>
{counter}
</div>
);
}
Body.defaultProps = {
counter: 0
}
I don't know whether this is eligible for an answer but all your concerns could be resolved by declaring your default value as a constant in the app. That means;
const Parent = () => {
const somethingUndefined;
return (
<>
<Child prop={somethingUndefined} />
</>
);
};
const Child = ({ prop = {a: 1} }) => {
const [x, setX] = React.useState(1);
React.useEffect(() => {
setX(x + 1);
}, [prop]);
return <div>{x}, {prop.a}</div>;
};
You can change the above code to
const Parent = () => {
const somethingUndefined;
return (
<>
<Child prop={somethingUndefined} />
</>
);
};
const defaultPropValue = {a: 1};
const Child = ({ prop = defaultPropValue }) => {
const [x, setX] = React.useState(1);
React.useEffect(() => {
setX(x + 1);
}, [prop]);
return <div>{x}, {prop.a}</div>;
};
This will not cause any infinite loops.
The difference bet these two:- In the first, the prop is initialized to a new value ie, {a: 1} and on every state update, this will be a new object (the new object will be in a new memory location), and it invokes the callback again.
In the second, we initialized and assigned the {a: 1} to defaultPropValue which will not change. Then we assigned this defaultPropValue to prop so that on every re-render, the value assigned to the prop will be the same ( or from the same memory location). So it works as expected.
Hope the idea is clear!
The useEffect() will run the first time and invoke the setX() then:
setX()will update the state ofxwhich will trigger the component to re-render again.propwill receive a new objectconst Child = ({ prop = {a: 1} }) => {useEffect()will run again and invoke thesetX()
the whole process repeats again, This causes an infinite loop.
Instead you could pass a default value to a property and use it in the useEffect() dependencies array
const Parent = () => {
let somethingUndefined; // babel complains if we use `const` without value
return (
<div>
<Child prop={somethingUndefined} />
<Child prop={{ a: 3 }} />
</div>
);
};
const Child = ({ prop = {} }) => {
const { a = 1 } = prop;
const [x, setX] = React.useState(1);
React.useEffect(() => {
setX(x + 1);
}, [a]);
return <div>{x}, {a}</div>;
};
ReactDOM.render(<Parent />, document.getElementsByTagName('body')[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>