如何在本机中实现可折叠的盒子?

时间:2018-01-22 07:38:37

标签: react-native jsx collapse

我正在尝试在native native中实现一个可折叠的盒子。它对于虚拟数据工作正常。但是,当我试图从服务器列出数据响应时,我收到错误。我在响应中使用map方法列出详细信息。但是显示错误evaluating this.state.details.map。我也很困惑在哪里放置map method.Below是我尝试过的代码。我将此文档引用到collapsible框。

示例

class DetailedView extends Component{
    constructor(props){
        super(props);
        this.icons = {
            'up'    : require('../Images/Arrowhead.png'),
            'down'  : require('../Images/Arrowhead-Down.png')
        };

        this.state = {
            title       : props.title,
            expanded    : true,
            animation   : new Animated.Value()
        };
    }
     toggle(){
        let initialValue    = this.state.expanded? this.state.maxHeight + this.state.minHeight : this.state.minHeight,
            finalValue      = this.state.expanded? this.state.minHeight : this.state.maxHeight + this.state.minHeight;

        this.setState({
            expanded : !this.state.expanded
        });

        this.state.animation.setValue(initialValue);
        Animated.spring(
            this.state.animation,
            {
                toValue: finalValue
            }
        ).start();
    }

  _setMaxHeight(event){
        this.setState({
            maxHeight   : event.nativeEvent.layout.height
        });
    }

    _setMinHeight(event){
        this.setState({
            minHeight   : event.nativeEvent.layout.height
        });
    }
    state = {details: []};
    componentWillMount(){
        fetch('https://www.mywebsite.com' + this.props.navigation.state.params.id )
        .then((response) => response.json())
        .then((responseData) =>
          this.setState({
              details:responseData
              })
              );
    }
    render(){
           let icon = this.icons['down'];

        if(this.state.expanded){
            icon = this.icons['up'];
        }


 return this.state.details.map(detail =>
            <Animated.View 
                style={[styles.container,{height: this.state.animation}]}>
                {detail.data.curriculum.map(curr =>
                <View onLayout={this._setMinHeight.bind(this)}>
                <Card>
                <CardSection>
                <View style={styles.thumbnailContainerStyle}>
                <Text style={styles.userStyle}>
                Hii
                </Text>
                </View>
                <TouchableHighlight onPress={this.toggle.bind(this)} 
            underlayColor="#f1f1f1">
                <Image style={styles.buttonImage} source={icon}></Image>
                </TouchableHighlight>
                </CardSection>
                </Card>
                </View>   

                <View style={styles.body} onLayout={this._setMaxHeight.bind(this)}>
                    {this.props.children}   
                    <Card>
                    <CardSection>
                    <Text>{this.props.navigation.state.params.id}</Text>
                    </CardSection>
                    </Card>
                </View>
                )}
            </Animated.View>
        );
  }
}

这是带有虚拟数据的工作代码的屏幕截图

Also this is the screenshot of working code with dummy data

1 个答案:

答案 0 :(得分:1)

<强> 1。解决错误:

您正在进行的API调用是异步的,一旦调用API,代码将继续执行,然后再从API获取响应。在有任何细节之前,组件会尝试映射this.state.details

这里的解决方案是,您需要在安装组件时最初设置ActicityIndi​​cator / Loader,一旦从API获取详细信息/响应,状态就会发生变化,然后您可以通过this.state.details

将空详细信息数组添加到初始状态。 state = { details:[] }

然后将return this.state.details.map(detail....置于if这样的条件下

if(this.state.details.length > 0) {
<map here>
} else {
return <ActivityLoader />
}

<强> 2。在哪里放置地图methiod

你需要将它放在一个函数中并从你的render方法中调用该函数。

showDetailsFunction() {
 return this.state.details.map(detail =>
}

render() {
 return(
   {this.showDetailsFunction()}
 )
}