当其自身状态更改时,React本机复选框会折叠手风琴

时间:2019-05-24 03:31:00

标签: javascript react-native

当我单击复选框以更改状态时,嵌套在其中的手风琴也会折叠。

这很奇怪;我可以单击下面的文字,手风琴不会折叠。

这是组件的代码;在CollapseBody中查看:

import React, { Component } from 'react';
import { View, Text, Modal, TouchableHighlight } from 'react-native';
import {Collapse,CollapseHeader, CollapseBody, AccordionList} from 'accordion-collapse-react-native'
import { loadLeagues } from '../actions'
import { connect } from 'react-redux'
import Checkbox from 'react-native-modest-checkbox'

class LeagueSelect extends Component {

            state = {
                modalVisible: false,
                checked: true
            }



    setModalVisible(visible) {
        this.setState({modalVisible: visible});
    }

    componentDidMount() {
        this.props.loadLeagues()
    }

    render() {
      return ( 
        <View style={{marginTop: 22}}>
        {console.log('in league', this.props)}
              <Modal
                animationType="slide"
                transparent={false}
                visible={this.state.modalVisible}
                onRequestClose={() => {
                  Alert.alert('Modal has been closed.');
                }}>

                <View style={{marginTop: 100}}>

                    <TouchableHighlight
                        onPress={() => {
                            this.setModalVisible(!this.state.modalVisible);
                        }}
                    >
                        <Text>Hide Modal</Text>
                    </TouchableHighlight>

                    <Collapse >
                        <CollapseHeader>
                            <Text>Leagues</Text>
                        </CollapseHeader>
                        <CollapseBody>
                            {this.props.league === null ?'' : this.props.league.map(
                                (v, i) => {
                                    return(
                                            <View>
                                                <Checkbox
                                                    label={v.acronym}
                                                    onChange={() => { this.setState({ checked: false})}}
                                                    checked={this.state.checked}
                                                />
                                                <Text>{v.acronym}</Text>
                                            </View>
                                    )
                                }
                            )}
                        </CollapseBody>
                    </Collapse>

                </View>

              </Modal>

              <TouchableHighlight
                onPress={() => {
                  this.setModalVisible(true);
                }}>
                <Text>Show Modal</Text>
              </TouchableHighlight>

            </View>
      );
    }
  }

function mapStateToProps(state) {
    return {
      league: state.league.league
     }
   }

export default connect(mapStateToProps, { loadLeagues })(LeagueSelect);

这是行为的视频;无法实际看到就很难描述:https://streamable.com/sbqab

1 个答案:

答案 0 :(得分:0)

您确定没有其他事情在干扰它吗?我使用您提供的代码构建了一个小示例项目,它似乎运行良好。

Working Demo

另一件事(无关)-两个框都使用相同的checked状态,因此单击其中一个将更改另一个框的状态。我认为这不是您想要的,所以我继续设置您的状态,以保留每个复选框的条目。

这是在该gif中运行的完整代码的副本:

import React, { Component } from 'react';
import { View, Text, Modal, TouchableHighlight } from 'react-native';
import { Collapse, CollapseHeader, CollapseBody, AccordionList } from 'accordion-collapse-react-native'
import Checkbox from 'react-native-modest-checkbox'

export default class App extends Component {
  state = {
    modalVisible: false,
    checked: {},
  }

  // hardcoded props
  league = [
    { acronym: 'NBA' },
    { acronym: 'NFL' },
  ];

  setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  componentDidMount() {
    const checked = this.league.reduce((acc, cur) => ({
      ...acc,
      [cur.acronym]: false,
    }), {});
    this.setState({ checked });
  }

  render() {
    return (
      <View style={{marginTop: 22}}>
        <Modal
          animationType="slide"
          transparent={false}
          visible={this.state.modalVisible}
          onRequestClose={() => {
            Alert.alert('Modal has been closed.');
          }}
        >
          <View style={{marginTop: 100}}>
            <TouchableHighlight
              onPress={() => {
                this.setModalVisible(!this.state.modalVisible);
              }}
            >
              <Text>Hide Modal</Text>
            </TouchableHighlight>
            <Collapse>
              <CollapseHeader>
                <Text>Leagues</Text>
              </CollapseHeader>
              <CollapseBody>
                {this.league === null ? '' : this.league.map(
                  (v, i) => (
                    <View key={v.acronym}>
                      <Checkbox
                        label={v.acronym}
                        onChange={() => this.setState({
                          checked: {
                            ...this.state.checked,
                            [v.acronym]: !this.state.checked[v.acronym]
                          }
                        })}
                        checked={this.state.checked[v.acronym]}
                      />
                      <Text>{v.acronym}</Text>
                    </View>
                  )
                )}
              </CollapseBody>
            </Collapse>
          </View>
        </Modal>
        <TouchableHighlight
          onPress={() => {
            this.setModalVisible(true);
          }}>
          <Text>Show Modal</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

需要注意的关键部分是复选框:

<Checkbox
  label={v.acronym}
  onChange={() => this.setState({
    checked: {
      ...this.state.checked,
      [v.acronym]: !this.state.checked[v.acronym]
    }
  })}
  checked={this.state.checked[v.acronym]}
/>

和“ props”中的状态初始化(我已经为示例进行了硬编码):

// hardcoded props
league = [
  { acronym: 'NBA' },
  { acronym: 'NFL' },
];

...

componentDidMount() {
  const checked = this.league.reduce((acc, cur) => ({
    ...acc,
    [cur.acronym]: false,
  }), {});
  this.setState({ checked });
}