Check Box is not unchecking when clicked again - React Native

Asked

Viewed 497 times

0

I have a code with 3 Checkbox and when pressed it does not uncheck... Another remark, as I would for when the "UE/HQB" is selected and the others stay disabled={true} or by first selecting any of the others this "UE/HQB" becomes disabled={true}

I’m using: https://github.com/react-native-community/react-native-checkbox

// Estrutura de CheckBox (isso dentro do state) 
checkboxes: [{
    id: 1,
    title: 'UE/HQB',
    checked: false,
}, {
    id: 2,
    title: 'Exportável',
    checked: false,
}, {
    id: 3,
    title: 'Não exportável',
    checked: false,
}],
// Função que lida com o estado dos CheckBox
toggleCheckbox(id) {
    const changedCheckbox = this.state.checkboxes.find(cb => cb.id === id);
    changedCheckbox.checked = !changedCheckbox.checked;
    const checkboxes = Object.assign(
        {},
        this.state.checkboxes,
        changedCheckbox
    );

    this.setState({ checkboxes });
}

Now the:

// Dentro do return
<CheckBox
    key={cb.id}
    title={cb.title}
    checked={cb.checked}
    onPress={() =>
        this.toggleCheckbox(
            cb.id
        )
    }
/>
  • You are using the https://github.com/react-native-community/react-native-checkboxlibrary??

  • Yes sant0will the one I’m using!

2 answers

0


First you are apparently using the Checkbox version of React-Native-Elements. Example:

<CheckBox
    title="Titulo"
    checked={this.state.checked}
    onPress={() => this.setState({checked: !this.state.checked})}
/>

Already to use the React-Native-community/checkbox you should follow the following example:

<CheckBox
    value={true}
    disabled={false}
/>

With this, you must create a View with the Checkbox and the text that will be shown:

{this.state.checkboxes.map((cb, index) => (
     <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}>
          <CheckBox
             value={cb.checked}
             onChange={() => this.toggleCheckbox(cb.id)}
          />
          <Text>{cb.title}</Text>
      </View>
))}

Finally, the main problem was its function that changed the status of checkboxes. It is interesting, when you are dealing with arrays in the states, create variable identics to these arrays and finally set in the state. Function ends up being like this:

toggleCheckbox(id) {
    // Cria uma variavel "cópia do state dos checkboxes"
    let array_checkboxes = this.state.checkboxes;

    // Percorre a lista
    array_checkboxes.map(cb => {
      // Se encontrar o item que foi clicado na lista
      if (cb.id === id) {
        // Inverte o estado do checkbox
        cb.checked = !cb.checked;
      }
    });

    // Por fim atribui ao estado a listagem que alteramos
    this.setState({
      checkboxes: array_checkboxes,
    });
}

The most important thing really is to use this variable copy to be able to manipulate easily.

Complete code

Functioning

0

I think that lib doesn’t work or wouldn’t work on Ios if that’s where you’re testing it. I remember that when I needed to do it myself I created the Component, the idea is very simple is a (square, circle ...) with an icon inside.

I made an example by placing the letter 'A' which you can replace with an icon and change the styles depending on the value change.

const data = [
  {
      id: 1,
      title: 'UE/HQB',
      checked: false,
  },
  {
      id: 2,
      title: 'Exportável',
      checked: false,
  },
  {
      id: 3,
      title: 'Não exportável',
      checked: false,
  },
]


function App() {
  const [checkboxes, setCheckboxes] = useState(data)

  useEffect(() => {
    // TO see every time when the checkboxes has changed
    console.log(checkboxes)
  }, [checkboxes])

  function handleToggle(id) {
    const newCheckboxes = checkboxes.map(item => {
      if(item.id === id) {
        item.checked = !item.checked
        return item
      }
      return item
    }) 

    setCheckboxes(newCheckboxes)
  }

  function renderItem({ item }) {
    return (
      <Checkbox 
        id={item.id}
        name={item.title}
        value={item.checked}
        handleToggle={handleToggle}
      />
    )
  }

  return (
    <View style={styles.container}>
      <View style={styles.listContainer}>
        <FlatList
          contentContainerStyle={styles.listContainer}
          keyExtractor={(item) => item.id.toString()}
          data={checkboxes}
          renderItem={renderItem}
        />
      </View>
    </View>
  )
}

const styles  = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },

  listContainer: {
    height: 300,
    padding: 16
  }
})



  //checkbox
export default function Checkbox({
    name = '',
    handleToggle,
    value = false,
    id,
    isDisabled = false,
}) {
  return (
    <View style={styles.container}>
        <TouchableOpacity
            onPress={() => handleToggle(parseInt(id))}
            style={styles.checkbox}
            disabled={isDisabled}
        >
            {value && <Text>A</Text>}
        </TouchableOpacity>
        <Text>{name}</Text>
    </View>
  )
}

const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        width: '100%',
        height: 60
    },

    checkbox: {
        width: 40,
        height: 40,
        borderWidth: 1,
        alignItems: 'center',
        justifyContent: 'center'
    }
})

Regarding disabling, you make your logic when changing the 'value' but an ideal tip is that each component is independent.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.