Do you want to request a feature or report a bug?
I am proposing adding a warning in development.
What is the current behavior?
when I do this.setState(({ bool }) => { bool: !bool });
this is valid javascript but is meaningless in React. ESLint:no-label helps to catch this but we can probably do one better by building a warning into dev-mode React itself.
sandbox demo: https://codesandbox.io/s/xopj5nx07o
What is the expected behavior?
warn when a function is applied to setState that returns undefined. if the user wants to indicate nothing changed they should return null.
I wish we did this earlier. Might be too late now because there’s probably a lot of code using this pattern. #strictmodeonly?
strictmodeonly works for me.
i'm not sure i understand, why would there be a lot of code using this pattern? accidental no-op is far more likely than intentional no-op?
also we'd just be doing a warning, i reckon if people think they know what they're doing we can let them ignore the warning. i dunno, is that inline with react's warning philosophy?
i'm not sure i understand, why would there be a lot of code using this pattern? accidental no-op is far more likely than intentional no-op?
Probably something like:
this.setState(state => { if (condition) return { foo: !state.foo } }) // no else
i'm not sure i understand, why would there be a lot of code using this pattern? accidental no-op is far more likely than intentional no-op?
I don't think it's necessarily more likely.
also we'd just be doing a warning, i reckon if people think they know what they're doing we can let them ignore the warning.
No, if we add a warning, we don't want people to ignore it. This devalues warnings.
strict mode it is
@sw-yx do you want to submit a PR for this?
yup i will attempt it this weekend if thats ok?
On Tue, Jun 26, 2018 at 10:48 PM Brandon Dail notifications@github.com
wrote:
@sw-yx https://github.com/sw-yx do you want to submit a PR for this?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react/issues/13111#issuecomment-400525534,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AiT1gtLGCY5yqTVilBJ9MI8KAYdTweB-ks5uAvJkgaJpZM4U4csG
.
ok i had a rough day and felt like i needed the psychological pickup so i'm going to try this now. for anyone following along i am marking out the thought process.
addWarning
branch./packages/react
for setState
packages/react
/packages/react-reconciler/src/ReactFiberClassComponent
where I find enqueueSetState(inst, payload, callback)
. setState
is called a "payload". ReactUpdateQueue.js
where I finally find "payload.call" (i could have skipped all this ceremony if i had known to search for "Updater function" which is commented everywhere setState is executedupdate.tag == ReplaceState
or UpdateState
. but i finally have the site where i can insert my warning. yay! 10% done.after adding my warning:
if (__DEV__) {
if (StrictMode && partialState === undefined) {
// Warn if partialState is undefined
// dev likely forgot to return in setState
// encourage returning null for no-op in strict mode
warning(
false,
'A setState updater function was called that returned undefined. ' +
'Check if you forgot to return a value in your setState updater ' +
'function. If a no-op was intended, return null.'
);
}
}
warning
is the old way of warning things, there's this "Strict Mode Warnings" that are being done where they seem to track warnings that have already been issued (i guess so as not to spam warnings). this is in ReactStrictModeWarnings.js
it('can use updater form of setState'
inside ReactIncremental-test.internal.js
. basically you want to look for the absolute simplest test that is close to your particular piece of code, so you can copy it and also colocate it. i have no idea what ReactIncremental is, looks like some incremental rendering thingy based on the other tests.expect(ReactNoop.flush).toWarnDev
yarn test --watch ReactIncremental-test.internal.js
Expected warning was not recorded: "A setState updater function was called that returned undefined. Check if you forgot to return a value in your setState updater function. If a no-op was intended, return null."
StrictMode
from ./ReactTypeOfNode
. it's a constant, not a derived boolean. i was misusing it.workInProgress.mode & StrictMode
instead.yarn test-prod
yarn prettier
yarn linc
(better than yarn lint
apparently)yarn flow dom
(has some options to choose) git add (relevant files only, dont add yarn.lock)
& `git commit -m "add warning for setState updater function returning undefined in strict mode"git push origin addWarning
(i have this in an addWarning
branch in my fork of React)I use with typescript ,now its's error "Cannot assign to 'state' because it is a constant or a read-only property."
I just write
constructor(props: any) {
super(props);
this.state = {
a:'a'
}
}
sorry, i dont think this has anything to do with my PR. are you commenting in the right issue? also if you want help with React + Typescript please see https://github.com/sw-yx/react-typescript-cheatsheet
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!
Most helpful comment
ok i had a rough day and felt like i needed the psychological pickup so i'm going to try this now. for anyone following along i am marking out the thought process.
addWarning
branch./packages/react
forsetState
packages/react
/packages/react-reconciler/src/ReactFiberClassComponent
where I findenqueueSetState(inst, payload, callback)
.setState
is called a "payload".ReactUpdateQueue.js
where I finally find "payload.call" (i could have skipped all this ceremony if i had known to search for "Updater function" which is commented everywhere setState is executedupdate.tag == ReplaceState
orUpdateState
. but i finally have the site where i can insert my warning. yay! 10% done.after adding my warning:
warning
is the old way of warning things, there's this "Strict Mode Warnings" that are being done where they seem to track warnings that have already been issued (i guess so as not to spam warnings). this is inReactStrictModeWarnings.js
it('can use updater form of setState'
insideReactIncremental-test.internal.js
. basically you want to look for the absolute simplest test that is close to your particular piece of code, so you can copy it and also colocate it. i have no idea what ReactIncremental is, looks like some incremental rendering thingy based on the other tests.expect(ReactNoop.flush).toWarnDev
yarn test --watch ReactIncremental-test.internal.js
Expected warning was not recorded: "A setState updater function was called that returned undefined. Check if you forgot to return a value in your setState updater function. If a no-op was intended, return null."
StrictMode
from./ReactTypeOfNode
. it's a constant, not a derived boolean. i was misusing it.workInProgress.mode & StrictMode
instead.yarn test-prod
yarn prettier
yarn linc
(better thanyarn lint
apparently)yarn flow dom
(has some options to choose)git add (relevant files only, dont add yarn.lock)
& `git commit -m "add warning for setState updater function returning undefined in strict mode"git push origin addWarning
(i have this in anaddWarning
branch in my fork of React)