реагировать на родной - присвоение массива объекта состояния переменной и обновление значения определенного элемента в массиве

1

У меня возникла проблема с доступом и назначением состояния массива в React Native. Мой код выглядит следующим образом:

export default class App extends Component{
  constructor(props){
    super(props)

    this.state = {
      boxChecked: [false, false],

      sportCat: []
    }
  }

  arrayHandler = (sportID, value) => {
    this.setState({boxChecked[sportID]: !this.state.boxChecked[sportID]})  //3rd problem
    if (value === true){
      this.setState({sportCat: [...this.state.sportCat, sportID]})
    } else if (value === false) {
      var idx = this.state.sportCat.indexOf(sportID)
      this.state.sportCat.splice(idx, 1)
    } else {
      console.log('boxstat undefined')
    }
    console.log(this.state.sportCat)
  }

  render() {
    return (
      <View style={styles.container}>

        <CheckBox
          sportID = { 1 }
          value = { this.state.boxChecked[sportID] }
          onChange = {(sportID, value) => {
            this.arrayHandler(sportID, value)
            console.log(value, 'value') //1st problem
            console.log(sportID, 'sportID')  //2nd problem
          }} />
      </View>
    )
  }
}

Я бы хотел спросить:


  1. когда я пытаюсь получить значение value, он возвращает undefined. Является ли проблема с тем, как я назначил переменную sportID?
  2. когда я пытаюсь получить значение sportID, он возвращает Proxy {dispatchConfig: {…}, _targetInst: FiberNode, etc...
  3. Когда я setState параметр setState таким образом, первый boxChecked[sportID] становится белым, а не синим в Visual Studio, что означает, что синтаксис считается недействительным. Является ли способ setState установки массива?

Ваша помощь очень ценится. Спасибо!

  • 0
    Что я понял из приведенного выше кода, так это то, что вы пытаетесь достичь функциональности нескольких флажков. Вы сохраняете информацию о выбранном флажке в состоянии sportCat, которую можете использовать для дальнейшей обработки. Это так?
  • 0
    @ МохаммедАшфак правильно! я пытаюсь собрать выбранную категорию спорта, на основе которой флажок установлен пользователем. массив обновляется каждый раз, когда пользователь проверяет / снимает флажок компонента.
Теги:
react-native

4 ответа

0
Лучший ответ

Решил проблемы.

Вот как мне удалось добиться нескольких функциональных возможностей флажка.

import React, {Component} from 'react';
import {Platform, 
  StyleSheet, 
  Text, 
  View, 
  CheckBox,
  TouchableOpacity
} from 'react-native';

export default class App extends Component{
  constructor(props){
    super(props)

    this.state = {
      sportID: [0,1,2,3],
      boxChecked: [false, false, false],

      sportCat: []
    }
  }

  arrayHandler = (ID) => {

    let boxChecked = [...this.state.boxChecked]  // use spread operator
    boxChecked[ID] = !boxChecked[ID]             // to mutate the value
    this.setState({boxChecked}, () => {          // of specific array
      const value = this.state.boxChecked[ID]
      if (value === true){
        this.setState({sportCat: [...this.state.sportCat, ID]})
      } else if (value === false) {
        var idx = this.state.sportCat.indexOf(ID)
        if (idx > -1){
          this.state.sportCat.splice(idx, 1)
        }
      }
      console.log(this.state.boxChecked)
      console.log(this.state.sportCat)
    })
  }


  render() {
    return (
      <View style={styles.container}>
        <CheckBox
          value = { this.state.boxChecked[0] }
          onValueChange = {() => {
            this.arrayHandler(0)
          }} />

        <CheckBox
          value = { this.state.boxChecked[1] }
          onValueChange = {() => {
            this.arrayHandler(1)
        }} />

        <CheckBox
          value = { this.state.boxChecked[2] }
          onValueChange = {() => {
            this.arrayHandler(2)
        }} />

        <TouchableOpacity
          style = {{ borderColor: 'black', borderWidth: 5, height: 50, width: 100}} 
          onPress = {() => {
            console.log(this.state.sportCat)
            console.log(JSON.stringify(this.state.sportCat))
          }}
        />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Оказывается, что setState() не мутирует значение состояния немедленно, вместо этого он создает ожидающий переход состояния. Доступ к значению состояния сразу после вызова метода setState() может вернуть неизмененное значение состояния. Вы должны вызвать вторую функцию обратного вызова для setState(), поскольку setState происходит асинхронно.

Более того, изменение значения конкретного индекса массива непосредственно в компоненте onValueChange невозможно, вам нужно использовать функцию оператора spread.

0

Существует еще один способ решить вашу проблему. Вы можете определить массив объектов, и каждый объект будет содержать свойства флажка. Таким образом вы можете динамически определять флажки.

  checkboxes =  [
    { id: 1, isChecked:false, sportID: 20}, 
    { id: 2, isChecked:false, sportID: 25}, 
    { id: 3, isChecked:false, sportID: 30}
  ]

Ниже приведен код использования указанного объекта.

constructor(props){
  super(props)
  this.state = {
   checkboxes:  [           
     { id: 1, isChecked:false, sportID: 20}, 
     { id: 2, isChecked:false, sportID: 25}, 
     { id: 3, isChecked:false, sportID: 30}
  ]
}
// Function To get The list of selected sports
getListOfSelectedSports(){
  selectedSports = [];
  this.state.checkBoxes.map((checkbox)=> { if(checkbox.isChecked)  selectedSports.push(checkbox.sportID) })
  return selectedSports;
}

renderCheckboxes(){
  return this.state.checkBoxes.map((checkbox, index, checkBoxArray) =>
      <CheckBox
        key={checkbox.id}
        style={{alignSelf:'center', margin:15}}
        onValueChange={(toggleValue) => {
            checkBoxArray[index].isChecked = toggleValue;
            this.setState({checkBoxes:checkBoxArray});
        }}
        value={ checkbox.isChecked }
      />
  )
}

render() {
  return (
    <View style={styles.container}>
    {this.renderCheckboxes()}
          .....
     //Rest of you Code
  )
} 
0

Кстати, вы можете манипулировать состоянием непосредственно из события компонента

Попробуйте это:

export default class App extends Component{
  constructor(props){
    super(props)

    this.state = {
      boxChecked: [false, false],

      sportCat: []
    }
  }

  render() {
    return (
      <View style={styles.container}>

        <CheckBox
          value = { this.state.boxChecked[0] }
          onValueChange = {() => { this.setState({ boxChecked[0]: !this.state.boxChecked[0] }) }} />
      </View>
    )
  }
}
  • 0
    спасибо за ответ, мас!
0

onChange возвращает собственный элемент, используйте onValueChange, он вызывает функцию с логическим значением, если он установлен или нет. Это пример реализации флажка

<View style={{ flexDirection: 'column'}}>
  <CheckBox />
  <View style={{ flexDirection: 'row' }}>
    <CheckBox
      value={this.state.checked}
      onValueChange={() => this.setState({ checked: !this.state.checked })}
    />
    <Text style={{marginTop: 5}}> this is checkbox</Text>
  </View>
</View>

Для проблемы setState вам необходимо обновить весь массив, а не прямые назначения.

Вы также, кажется, изменяете состояние, не используя setState здесь,

this.state.sportCat.splice(idx, 1)

Это нехорошо. Я думаю, вам нужно пройти через документы больше

  • 0
    Спасибо брат! ценю ответ :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню