React Native元素列表项开关不起作用

时间:2018-04-11 17:23:42

标签: javascript reactjs react-native

我有一个带有RN元素ListItem的SectionList,我隐藏了V形符号并将开关状态设置为状态变量。 onSwitch方法不起作用,或者至少我无法使其工作。

我尝试过几种不同的方法来实现它无济于事。

 <SectionList
            sections={[
                {title: 'Company Focus', data: this.state.focusNodes},
            ]}
            renderSectionHeader={({section}) => <Text style= 
            {styles.sectionHeader}>{section.title}</Text>}
            renderItem={({item}) => <ListItem style={styles.subTitle} key= 
            {item.id} title={item.name} 
            switchButton hideChevron switched= 
            {this.state.isNodeSelected} switchOnTintColor={'#00BCD4'} 

            onSwitch={(value) => {
               this._handleSwitch(value);

            }}/>} />




 _handleSwitch = (item) => {
    this.state.isNodeSelected = true;
    console.log(item);
    console.log(this.state.isNodeSelected);
    }

另一种方式:

    onSwitch={(value) => {
          this.setState(previousState => {
          return{previousState, isNodeSelected: value}})
                    }}/>} />

第一个例子中的开关只是移动然后向后移动。在第二个例子中,它将列表中的所有开关都打开或关闭,无论我打开/关闭哪一个

编辑 - 整个组件:)

  'use strict';
import React from 'react';
import { StyleSheet, 
  Text, 
  View,
  NavigatorIOS,
  ScrollView,
  Button, 
  PickerIOS,
  Dimensions,
  SectionList,
  TouchableHighlight,
} from 'react-native';
import {Header, ListItem, List} from 'react-native-elements';

import StepIndicator from 'react-native-step-indicator';

export default class FocusPage extends React.Component {

            constructor(props){
                super(props);
                this.state ={
                    data : [],
                    roleNodes: [],
                    skillNodes: [],
                    focusNodes: [],
                    // roleSelection: '',                
                    // childSelection: '',
                    isVisible: false,
                    currentPosition: 0,
                    selectedNodes: [],
                    isFocusNodeSelected: false
                }         
            }

            _createFocusNodesArray = (array) => {
                var nodeArray =[];
                for(var i = 0; i < array.length; i++){      
                    if(array[i].orderNumber === 2)                    
                    nodeArray.push(array[i]);        
                }
                return nodeArray;
            }

                _getFocusData = () => {
                    fetch('http://10.0.0.58:8082/api/getfocusnodes', {
                        method: 'GET'
                        })
                        .then((response) => response.json())  
                        .then((responseJson) => {

                        //   this.setState({
                        //     data: responseJson
                        //   })
                        var simpleArray = 
                        this._simplifyJsonArray(responseJson);
                        // console.log(simpleArray);
                        this.setState({
                            focusNodes: 
                        this._createFocusNodesArray(simpleArray),

                        })

                        })
                        .catch((error) => {
                        console.log(error);

                        //   this.setState({
                        //     isLoading: false,
                        //     message: 'Woops! ' + error
                        //   })
                        })     
                }

            //'http://10.0.0.58:8082/api/gettreenodes'
            //'http://192.168.6.217:8082/api/gettreenodes'
        componentDidMount = () => {
           this._getFocusData();
        }


        _simplifyJsonArray = (array) => {

            var tempArray = [];
            for(var i = 0; i < array.length; i++)
            {
                var tempNode = {
                    id: array[i].id,
                    name: array[i].name,
                    orderNumber: array[i].orderNumber,
                    isSelected: false
                }
                    tempArray.push(tempNode);  
            }
            return tempArray;
        }

        getSelection = (selectedItem) => {

            console.log(selectedItem);
            // selectedItem.isSelected = true;
            // this.state.isNodeSelected = true;

            for (let index = 0; index < this.state.focusNodes.length; 
              index++) {
                const element = this.state.focusNodes[index];
                if(element.name === selectedItem){
                    console.log(element.name);
                    this.state.isFocusNodeSelected = true;
                }
            }

            if (selectedItem.isSelected) {
                this.state.isFocusNodeSelected = true;
            }
            // console.log(this.state.isNodeSelected);          
            // for (let i = 0; i < this.state.focusNodes.length; i++) {
            //     const element = this.state.focusNodes[i];
            //     if (element.name === selectedItem) {
            //         element.isSelected = true;
            //         this.state.isNodeSelected = element.isSelected;
            //         this.state.selectedNodes.push(element);   
            //         console.log(this.state.isNodeSelected);          
            //     }
            //     else{
            //         this.state.isNodeSelected = false;
            //     }               
            // }          
            // console.log('The selected item: ' + selectedItem);
            // console.log('The selected Array: ' + this.state.selectedNodes);
        }

_handleSwitch = (item) => {
    this.state.isFocusNodeSelected = true;
    console.log(item);
    console.log(this.state.isFocusNodeSelected);
}




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

                     <SectionList
                    sections={[
                        {title: 'Company Focus', data: this.state.focusNodes},
                    ]}
                    renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
                    renderItem={({item}) => <ListItem style={styles.subTitle} key={item.id} title={item.name} 
                    switchButton hideChevron switched={item.isSelected} switchOnTintColor={'#00BCD4'} 
                    onSwitch={(value) => {
                        this.setState(previousState => {
                            return{previousState, isFocusNodeSelected: value}
                        })
                    }}/>} />

            </View>
        );
    }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  pageTitle:{
      fontSize: 27,
      textAlign: 'center',
      //margin: 20
  },
  sectionHeader:{
    fontSize: 20,
    backgroundColor: '#673AB7',
    height: 40,
    textAlign: 'center',
    padding: 10,
    color: 'white'

  },
  subTitle: {
    fontSize: 16,
    // textAlign: 'center',
    // marginTop: 20,
    backgroundColor: '#00BCD4'
  },
  popButton: {
    borderRadius: 10,
    padding: 5,
    // marginLeft: 5,
    marginRight: 5,
    backgroundColor: '#00BCD4',
    borderColor: 'black',
    borderWidth: 1,
  },
  subtitleView: {
    flexDirection: 'row',
    paddingLeft: 10,
    paddingTop: 5,
    textAlign: 'right'

  },
});

1 个答案:

答案 0 :(得分:1)

在您的第一个示例中,您的交换机被翻转的原因是您始终将交换机设置为true,因此它们永远不会设置为false

this.state.isNodeSelected = true;

但这不是唯一的问题。正如您在第二个示例中看到的那样,您可以通过将值设置为onSwitch作为value传递给我来解决此问题。非常好。现在关闭所有开关的问题是因为您对所有开关使用相同的state值。

switched={this.state.isNodeSelected}

所以当你更新isNodeSelected时,你正在为每个开关更新它。

要解决此问题,您需要在某处保留每个switched的{​​{1}}值;可能最简单的就是你传递给ListItem的内容。

sections

您传递到sections={[ {title: 'Company Focus', data: this.state.focusNodes}, ]} 道具的数据应保存在sections中,以便您可以更新其开关被翻转的特定项目。但是,如果没有看到您的state代码,就很难说出您正在做什么以及如何解决它。上面的解释应该足以让你找到解决方案。请记住,state也会获得一个renderItem参数,该参数显示在simple examples from the docs中,并在prop docs中进一步说明。

修改:通过编辑的信息和更改,我们现在有一个index,其中每个renderItem都有ListItem个值存储在{{1}中}}。因此,我们的目标是让switched更新的那个值。那么我们更新什么?

嗯,item.isSelected onSwitch道具正在从SectionList获取该数据(sections设置为什么)。因此,更新this.state.focusNodes中的正确值是需要发生的。正如我在上面提到的,一种方法是利用data的{​​{1}}参数:

focusNodes

备注

  • 我使用renderItem来确定哪些index需要更新。由于您使用的是renderItem={({item, index}) => <ListItem style={styles.subTitle} key={item.id} title={item.name} switchButton hideChevron switched={item.isSelected} switchOnTintColor={'#00BCD4'} onSwitch={(value) => { let focusNodes = [...this.state.focusNodes]; focusNodes[index].isSelected = value; this.setState({ focusNodes, isFocusNodeSelected: value }); }} /> } ,因此请阅读文档以了解如何确定此index值。一旦开始使用多个部分,请小心并且不要做出假设。我这样说是因为......
  • 我注意到您focusNodes中的SectionList未使用。如果您最终重构并更改index道具以使用此版本,或者将data移动到其中,则必须重构正在更新的内容。注意并理解数据的结构,而不是对state
  • 做出错误的假设
  • 如果遗失的sections让你失望,我会在focusNodes中使用简写来使其更清洁。
  • 我假设传递给index的{​​{1}}是previousState需要更新的正确布尔值。我没有测试项目设置来运行它来确认。