-
Notifications
You must be signed in to change notification settings - Fork 47.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A note on function components default parameters #16905
Comments
This issue has come up in a few discussions around default parameters, and our recommendation has generally been to use a stable "empty array" value (or object, or no-op function), if this is a concern - e.g. const emptyArray = [];
function Example({ optionalArray = emptyArray }) {
// ...
} Our docs are open source, also on GitHub, and PRs that improve them are always welcome from the community! |
I'm going to close this issue but a PR would be welcome in the other repo! |
Cool @bvaughn - (kudos on the Profiler btw!) Using a scope object like this could cause (in my real use case) a bug when the array is mutated by an instance and next renders would have the mutated array as default argument. I ended up using Example.defaultProps = { get optionalArray () { return [] } } I'll create a PR on the docs repo 💯 |
A Mutation is discouraged in props. It sounds like a |
Props should always be read-only. This is one of the core rules of React: If your component needs to mutate an incoming array, it could store a shallow clone of the array in state and mutate that? e.g. const emptyArray = [];
function Example({ optionalArray = emptyArray }) {
const [editableArray, setEditableArray] = useState(() => Array.from(optionalArray));
// ...
} |
True that @nortonwong, on every new props that component would have also a new array as a default param. @bvaughn I wasn't aware that |
Yup! It only calls the initializer function when the state is initialized. https://reactjs.org/docs/hooks-reference.html#lazy-initial-state |
When you define default parameters for a function component, the component will have brand new parameters on every render (function call) - in case they aren't defined.
Turns out that by doing this way we are not actually defining
defaultProps
(as possibly wanted) but creating objects in every function call, causing an infinite loop if Hook dependency array relies on the default parameter.Maybe not a real issue here, but found that today and felt there should be a note about this somewhere in the docs.
Relevant code:
See: https://codesandbox.io/s/jest-test-mfz1z?fontsize=14
The text was updated successfully, but these errors were encountered: