react-native-checkbox icon indicating copy to clipboard operation
react-native-checkbox copied to clipboard

Controlled Component

Open SConaway opened this issue 4 years ago • 19 comments

Bug report

Summary

This seems like it's a controlled component since it takes value and onValueChange as props. But, if value changes outside of the checkbox, it doesn't update. To me, this makes it not a controlled component. Am I missing something here?

Environment info

react-native info output:

info Fetching system and libraries information...
System:
    OS: macOS 11.0
    CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
    Memory: 189.56 MB / 16.00 GB
    Shell: 5.8 - /usr/local/bin/zsh
  Binaries:
    Node: 14.7.0 - /private/var/folders/5w/5dc75xj91xx_mvq7prvkplx80000gn/T/xfs-46c4d0de/node
    Yarn: 2.0.0-rc.36 - /private/var/folders/5w/5dc75xj91xx_mvq7prvkplx80000gn/T/xfs-46c4d0de/yarn
    npm: 6.14.7 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/lib/ruby/gems/2.7.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.0, DriverKit 20.0, macOS 11.0, tvOS 14.0, watchOS 7.0
    Android SDK:
      API Levels: 29
      Build Tools: 29.0.2, 30.0.1
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6514223
    Xcode: 12.0/12A8179i - /usr/bin/xcodebuild
  Languages:
    Java: 14.0.1 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: ^16.13.1 => 16.13.1
    react-native: ^0.63.2 => 0.63.2
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 0.4.2

Steps to reproduce

  1. Have a checkbox in your app whose value is controlled via React's useState
  2. Modify the value through something like an Alert.
  3. Now the Checkbox and value are out of sync.

Describe what you expected to happen:

I expect the checkbox to match the value. If I change the value, it should check / uncheck accordingly.

Reproducible sample code

const [toggleCheckBox, setToggleCheckBox] = useState(false)

return 
    <>
	<CheckBox
		disabled={false}
		value={toggleCheckBox}
		onValueChange={(newValue) => setToggleCheckBox(newValue)}
	/>
	<Button
		onPress={() => {
			Alert.alert(
				'Alert Title',
				'My Alert Msg',
				[
					{
						text: 'Ask me later',
						onPress: () => setToggleCheckBox(!toggleCheckBox),
					},
					{
						text: 'No',
						style: 'cancel',
					},
				],
				{cancelable: false},
			);
		}}
		title="toggle"
	/>
    </>

SConaway avatar Aug 11 '20 19:08 SConaway

I'm having the same issue, some news?

renanogueira avatar Aug 17 '20 21:08 renanogueira

I'd be willing to work on this, but it's all native code (not a strength of mine)

SConaway avatar Aug 17 '20 22:08 SConaway

I think these should have been resolved by now. It is such a basic and important functionality. I know its very easy for me to say to resolve the bug but due to my lack of native development knowledge I am not able to help you.

BraveEvidence avatar Aug 28 '20 11:08 BraveEvidence

That's my issue. Especially since this uses a library for the iOS part.

SConaway avatar Aug 28 '20 15:08 SConaway

@SConaway I think the Facebook engineers should help as well as the docs recommend this library

BraveEvidence avatar Aug 29 '20 03:08 BraveEvidence

@nicholaslee119 any help about this?

rodgomesc avatar Sep 04 '20 21:09 rodgomesc

Sorry for the delay, we will figure this out in a few weeks 😢

nicholaslee119 avatar Sep 08 '20 03:09 nicholaslee119

@nicholaslee119 No need to be sorry, open source is difficult, thank you for replying

BraveEvidence avatar Sep 08 '20 08:09 BraveEvidence

The way I resolved this issue, was to use a TouchableHighlight that initially wraps the Checkbox with a disabled value of true. Then conditionally show the Checkbox if the value is true or the TouchableHighlight e.g.

          {someValue ? (
            <CheckBox
              value={someValue}
              onValueChange={onValueChange}
            />
          ) : (
            <TouchableHighlight
              onPress={onValueChange}
              underlayColor="grey"
            >
              <CheckBox
                disabled={true}
                tintColors={{ false: grey, true: 'grey' }}
              />
            </TouchableHighlight>
          )}

This is a massive hack, but it works as expected for me. Hope this issue can be resolved soon.

agreco avatar Sep 08 '20 13:09 agreco

https://github.com/react-native-community/react-native-checkbox/blob/be115e479782704382348544d6ec018daa2aa833/example/App.js#L125-L141

I have tried to reproduce this in our example code, but the value of checkbox has been changed after clicking the toggle button just like above

I did not use the function component with the react hook, but I think it is the same with setState in the class component.

Any detail which I did not notice to reproduce this bug?

nicholaslee119 avatar Sep 10 '20 01:09 nicholaslee119

https://github.com/react-native-community/react-native-checkbox/blob/223e604f4fbe1abd57a476d743d294f6de82a38a/example/AppFunction.tsx#L25-L86

I also tried to reproduce this in the function component, but it also works well is iOS and Android

Sep-10-2020 11-10-30

Sep-10-2020 11-17-57

nicholaslee119 avatar Sep 10 '20 02:09 nicholaslee119

@nicholaslee119 If you do not do anything in onValueChange then the checkbox should not toggle on clicking it right. But it changes.

  <CheckBox value={value} /> 

Here the value would never change. But onClicking CheckBox it toggles.

a-c-sreedhar-reddy avatar Sep 10 '20 02:09 a-c-sreedhar-reddy

Here was my component: <Checkbox value={getSelectedFact} onValueChange={(newValue) => setSelectedFact(newValue)} />. Then, in some other function, I would toggle getSelectedFact.

I am modifying the example to match and will upload relevant code.

SConaway avatar Sep 10 '20 02:09 SConaway

https://github.com/react-native-community/react-native-checkbox/issues/42#issuecomment-624724633

Based on this comment value prop is used to define the initial value of the checkbox. But the better version would be to have a controlled component checkbox with a value prop (eg: TextInput)

a-c-sreedhar-reddy avatar Sep 10 '20 02:09 a-c-sreedhar-reddy

Yeah. That's what needs to change in my opinion

SConaway avatar Sep 10 '20 03:09 SConaway

So oddly enough, I was unable to reproduce it with the latest version in a fresh-RN project. I was unable to successfully build the example, so that's why I created a quick test project. I am deploying my original idea into the actual project and will test it there.

Feel free to close this issue if you'd like

SConaway avatar Sep 10 '20 23:09 SConaway

@SConaway I am still facing the issue. I am using 0.5.3 version

BraveEvidence avatar Sep 14 '20 06:09 BraveEvidence

Same issue here. The only solution was to wrap the Checkbox as @agreco said, keep the Checkbook disabled and control if its checked or not with the TouchableHighlight.

joseygordev avatar Nov 05 '20 19:11 joseygordev

At least should have two versions if you like, one controlled and another uncontrolled.

josegoval avatar Nov 05 '21 11:11 josegoval

any progress?

hkar19 avatar Sep 13 '22 08:09 hkar19

@nicholaslee119 If you do not do anything in onValueChange then the checkbox should not toggle on clicking it right. But it changes.

  <CheckBox value={value} /> 

Here the value would never change. But onClicking CheckBox it toggles.

I believe this is the key right here. Clicking it changes the value. Clicking it should not change the value, just call the onChange / onValueChange callbacks. Any plans to fix this?

DTwigs avatar Nov 10 '22 20:11 DTwigs

such a turn off from this library,

MCervenka avatar Dec 01 '22 14:12 MCervenka

Can anyone suggest any different module to display checkbox in react-native? This module's development seems to be dead.

JJSLIoT avatar Mar 21 '23 07:03 JJSLIoT