Checkbox not Rendering or Changing Checked value when state is changing - checkbox

I have to change the value of Checkbox to Checked from Unchecked and vise-versa.
For that I am changing state on button click.
and if 'checked' state value is 'true' then Checkedbox should be checked. But, It not.
I have used property 'checked' and assigned state's boolean value.
So, it should render when state going to be changed but it not changing.
Is there any other way to render Checkbox ?

This is a code sample how to do that
class App extends Component {
state = {
isChecked: false
};
render() {
return (
<View>
<CheckBox
value={this.state.isChecked}
onValueChange={() =>
this.setState({
isChecked: !this.state.isChecked
})
}
/>
</View>
);
}
}

If you are using redux-form then, this is your solution :
<Field name="AcceptTAndC" component={(props) => {
return (
<View>
<ListItem>
<CheckBox {...props.input} checked={props.input.value ? true : false} onPress={() => {
const val = !props.input.value;
props.input.onChange(val);
this.setState({ acceptTAndC: val });
}} />
<Text> I accept <Text onPress={() => this.refs.termsModal.open()}>this terms and conditions</Text></Text>
</ListItem>
</View>
)
}} validate={[acceptTerms]}/> // "acceptTerms" is validation rules that imported from other file, but you may not need it for this
You can check details from here code and output

as mentioned above by #Amila Dhulanjana, this function only changes the value of assigned state value, but it will not update the checkbox in HTML view until you assign the checked field.
class App extends Component {
state = {
isChecked: false,
};
render() {
return (
<View>
<CheckBox
value={this.state.isChecked}
checked={this.state.isChecked}
onValueChange={() =>
this.setState({
isChecked: !this.state.isChecked,
})
}
/>
</View>
);
}
}

Related

How to set color of only the clicked IconButton - ReactJS?

I am new to React JS. I have multiple IconButtons. OnClick I want only the clicked button to change its color. I have used state but when state changes, the color of all buttons change. What approach should I apply? Is there a way to change color without using state? Is there need of a key or id?
The code I have provided is cropped (means it only contains parts I think are relevant).
class Utilitybar extends React.Component {
constructor(props) {
super(props);
this.state = {
bgColor: "default"
};
}
render() {
return (
<div>
<IconButton color={
this.state.bgColor
}
onClick={
() => {
this.props.vidToggle();
if (this.state.bgColor === "default") {
this.setState({ bgColor: "primary" })
} else {
this.setState({ bgColor: "default" })
}
}
}>
<FaPlayCircle />
</IconButton>
<IconButton color={
this.state.bgColor
}
onClick={
() => {
this.props.fileToggle();
if (this.state.bgColor === "default") {
this.setState({ bgColor: "primary" })
} else {
this.setState({ bgColor: "default" })
}
}
}>
<FaRegFileAlt />
</IconButton>
</div>
);
}
}
I expect only clicked button to change color. But obviously they all use the same state, and when state is changed then the color of all buttons is changed.
Instead of storing a shared property (bg color), store the information you really need : i.e. the pressed button
class Utilitybar extends React.Component {
constructor(props) {
super(props)
this.onButtonClicked = this.onButtonClicked.bind(this)
this.state = { currentButton: null }
}
onButtonClicked (id) {
this.setState({ currentButton: this.state.currentButton === id ? null : id })
}
render(){
return (
<div>
<IconButton
color={this.state.currentButton === 0 ? "primary" : "default" }
onClick={() => this.onButtonClicked(0)}>
<FaPlayCircle/>
</IconButton>
<IconButton
color={this.state.currentButton === 1 ? "primary" : "default" }
onClick={() => this.onButtonClicked(1)}>
<FaRegFileAlt/>
</IconButton>
</div>
);
}
}
edit: the idea is to store an ID corresponding to one of your buttons (note that I assumed only one button can be clicked at a time). This ID is put in the component state. Then each button will check its ID against the ID in the state; if it match then it will render a different background.
Since you probable want the button to be unpressed after a second click, the onButtonClicked checks the current ID before updating the state, and if it is the same as the new one, it clears the stored ID instead

react-select prevent menu to open onInputChange

I'm trying to use the react-select component as an input and a select component.
Doing so I would like to prevent the menu to open while the user is typing the input.
I just can't find a way to update this behavior by either a prop or updating the onInputChange method.
My problem if I decide to use a controlled state with the menuIsOpen prop is that I can't manage to reopen the Menu control is clicked.
Here is what I have so far, do you guys any idea of how this could be achieved ?
<StyledSelect
components={{ IndicatorSeparator }}
{..._.omit(this.props, [])}
filterOption={() => true}
inputValue={inputValue}
onChange={value => {
this.select.setState({ menuIsOpen: false });
this.setState({ selectValue: value });
}}
onInputChange={(value, event) => {
if (event && event.action === 'input-change') {
this.setState({ inputValue: value });
}
}}
openMenuOnClick={false}
/>
Example
I think you are in the right direction using onInputChange and I would add a controlled menuIsOpen props like the following code:
class App extends Component {
constructor(props) {
super(props);
this.state = {
menuIsOpen: false
};
}
openMenu = () => {
this.setState({ menuIsOpen: !this.state.menuIsOpen });
};
onInputChange = (props, { action }) => {
if (action === "menu-close") this.setState({ menuIsOpen: false });
};
render() {
const DropdownIndicator = props => {
return (
components.DropdownIndicator && (
<div
onClick={this.openMenu}
style={{ display: "flex", alignItems: "center" }}
>
<span style={{ marginLeft: 12 }}>kg</span>
<components.DropdownIndicator
{...props}
onClick={() => {
console.log("ici");
}}
/>
</div>
)
);
};
return (
<Select
components={{ DropdownIndicator }}
options={options}
onChange={this.onChange}
onInputChange={this.onInputChange}
menuIsOpen={this.state.menuIsOpen}
/>
);
}
}
The idea with this code is to fire an onClick event on the DropdownIndicator custom component.
Here a live example.

why is my bind not working in constructor

I'm doing a very simple two button state. where if i click abutton, A component displays and if bbutton is clicked then component B. I'm mapping through array of items so that each of them have their own buttons state. Lets say if I click item 1's button B then I want only first Item B to show. Right now All of them gets triggered at once. I have bounded each of them in the constructor but still i'm unable to get only the once the once clicked to trigger and show the relevant component.
class Home extends Component {
constructor(props) {
super(props);
this.state = {
lists: []
showA: true,
showB: false
}
this.aButtonHandler = this.aButtonHandler.bind(this);
this.bButtonHandler = this.bButtonHandler.bind(this);
}
aButtonHandler = (e) => {
this.setState({
showA: true,
showB: false
})
}
bButtonHandler = (e) => {
this.setState({
showA: false,
showB: true
})
}
render(){
return (
<div>
{this.state.lists.map(detail =>
<li>{detail.id}</li>
<button onClick={(e) => this.aButtonHandler(e)} >see A</button>
<button onClick={(e) => this.bButtonHandler(e)} >see B</button>
{this.state.showA ?
<ComponentA /> : null
}
{this.state.showB ?
<ComponentB /> : null
}
)}
</div>
)
}
If you are using arrow functions no need to bind functions.
If you want to bind then change it to normal function like this.
aButtonHandler(e){...}
bButtonHandler(e){...}
If you want to use bind in constructor no need to use arrow function, just use regular functions and pass the function directly to onClick
aButtonHandler(e) { this.setState({ showA: true, showB: false }); }
bButtonHandler(e) { this.setState({ showA: false, showB: true }); }
render() {
return (
<div>
{this.state.lists.map(detail => (
<div>
<li>{detail.id}</li>
<button onClick={this.aButtonHandler}>see A</button>
<button onClick={this.bButtonHandler}>see B</button>
{this.state.showA ? <ComponentA /> : null}
{this.state.showA ? <ComponentB /> : null}
</div>
))}
</div>
);

React Native checkbox of a map select

I am mapping through an array of objects called abilities in React Native, that I retrieve from the backend and trying to select each one of them (abilities) assigned to each item. But selecting one of them, selects them all. How to effectively select a single checkbox in handleConfirm?
class Example extends Component {
constructor(props) {
super(props);
this.state = {
checked: false,
};
this.handleConfirm = this.handleConfirm.bind(this);
handleConfirm () {this.setState({ checked: true })}
render() {
const {
checked
} = this.state;
return (
<Container>
<Content contentContainerStyle={styles.container}>
<ListItem style={styles.listAllItems}>
{abilities.map((ability, index) =>
<Button
key={index}
iconLeft
style={styles.button}
>
<Text>{ability.name + '\n'}</Text>
<Right>
<CheckBox
checked={checked}
onPress={ this.handleConfirm()}/>
</Right>
</Button>
)}
</ListItem>
</Content>
</Container>
Below things you have missed in your code:
1] As you are mapping through array of object, you need to manage each checkbox state, which is missing in your code(i.e. you have used a single variable for maintaining check-boxes state which is not correct). You need a array for managing checked/unchecked status of each checkbox.
2] Also it has been observed that, you are handling only checked true condition. Actually you need to handle toggle(checked=>unchecked and unchecked=>checked).
I have made some modifications in your code for your issue and above specified changes as well:
class Example extends Component {
constructor(props) {
super(props);
this.state = {
checked: []
};
}
isItemChecked(abilityName) {
return this.state.checked.indexOf(abilityName) > -1
}
manageToggle = (evt, abilityName) => {
if (this.isItemChecked(abilityName)) {
this.setState({
checked: this.state.checked.filter(i => i !== abilityName)
})
} else {
this.setState({
checked: [...this.state.checked, abilityName]
})
}
}
render() {
return (
<Container>
<Content contentContainerStyle={styles.container}>
<ListItem style={styles.listAllItems}>
{abilities.map((ability, index) =>
<Button
key={index}
iconLeft
style={styles.button}
>
<Text>{ability.name + '\n'}</Text>
<Right>
<CheckBox
checked={this.isItemChecked(name)}
onPress={evt => this.manageToggle(evt, ability.name)}/>
</Right>
</Button>
)}
</ListItem>
</Content>
</Container>
do this for your onPress in your checkBox
onPress={()=>{ this.handleConfirm()}}

Stateless function components cannot hav refs

I'm building search page similar to Facebook or instagram. Basically if we press search button, it navigates to 'SearchScreen'. When its component is mounted, I want to set the search header is focused (cursor).
My problem is when I set TextInput ref as a prop. And I'm getting Stateless function components cannot have refs error. Is this right approach? Why is it not working? Do you know any better approach other than this?
I added _renderHeader private function to renderHeader props in FlatList.
This is _renderHeader
_renderHeader = () => {
return (
<View style={styles.layoutheader}>
<View style={styles.containerheader}>
<RkTextInput
rkType='row'
ref="sbar" /////////////////////HERE////////////
autoCapitalize='none'
autoCorrect={false}
label={<RkText rkType='awesome' style={{color:'white'}}>{FontAwesome.search}</RkText>}
placeholder='Search'
underlineWidth="1"
underlineColor="white"
style={styles.searchBarheader}
inputStyle={{color:'white'}}
labelStyle={{marginRight:0}}
value={this.state.inputText}
onChangeText={(inputText)=>{this.setState({inputText})}}
/>
<View style={styles.left}>
<RkButton
rkType='clear'
style={styles.menuheader}
onPress={() => {
this.props.navigation.goBack()
}}>
<RkText style={styles.titleText} rkType='awesome hero'>{FontAwesome.chevronLeft}</RkText>
</RkButton>
</View>
</View>
</View>
)
}
componentDidMount() {
this.refs.sbar.focus(); ////////// Here I want to focus RkTextInput when it's loaded
}
UPDATE here is actual code as requested
class SearchScreen extends Component {
static navigationOptions = ({navigation}) => ({
header: null
})
state = {
active: false,
inputText: ''
}
...
_renderRow = (row) => {
...
);
}
_renderHeader = () => {
...
}
render() {
return (
<FlatList
data={null}
renderItem={this._renderRow}
renderHeader={this._renderHeader}
keyExtractor={this._keyExtractor}
ListHeaderComponent={this._renderHeader}
/>
);
}
componentDidMount() {
this.refs.sbar.focus();
}
}
What seems to me is that you are not using the refs the right way. The way you are using them has been deprecated. You should follow this syntax:
<input
type="text"
ref={(input) => { this.textInput = input; }}
/>
and when you want to access it you can do this.textInput. In your case, this.textInput.focus().
You're using RkTextInput which is a functional component and it cannot have a ref. That's why you can't focus it.
I don't see a way to focus the input other than wrapping the Component, getting the ref of the root and finding your input element in order to focus it. A rough example :
class RoughExample extends React.Component {
componentDidMount() {
//find the input from your root
this.input = this.root.querySelector('input');
//if it exists, focus
this.input && this.input.focus();
}
render() {
<div ref={ (node) => {this.root = node;} }>
<RkTextInput />
</div>
}
}

Resources