反应本机-将状态对象的数组分配给变量并更新数组中特定元素的值

时间:2018-08-02 07:44:59

标签: javascript react-native

在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的值时,它返回未定义。我如何分配sportID变量是否有问题?
  2. 当我尝试获取sportID的值时,它返回Proxy {dispatchConfig: {…}, _targetInst: FiberNode, etc...
  3. 当我以这种方式键入setState参数时,第一个boxChecked[sportID]在Visual Studio中变成白色,而不是蓝色,这意味着该语法无效。我对setState数组的处理方式不正确吗?

非常感谢您的帮助。谢谢!

4 个答案:

答案 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)

这不是一件好事。 我认为您需要详细阅读文档

答案 1 :(得分: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>
    )
  }
}

答案 2 :(得分: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组件中更改数组的特定索引的值,您必须使用散布运算符函数。

答案 3 :(得分:0)

还有另一种解决问题的方法。您可以定义一个对象数组,每个对象将包含一个复选框的属性。这样,您可以动态定义复选框。

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

下面的代码显示了上面Object的用法。

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
  )
}