简体   繁体   中英

React doesn't render sub array of the props when it hidden before

I have a screen that pass data to a screen component template. Here is the template.

import React, { Component } from "react";
import { Text, View } from "react-native";
import { List, ListItem, Icon, Body, Right } from "native-base";
import { observer, inject } from "mobx-react/native";
import styles from "./styles";

@inject("view.app", "domain.user", "app", "routerActions")
@observer
class ListDropdown extends Component {
  constructor(props) {
    super(props);
    this.state = {
      categoryDrop: null,
    };
  }

    categoryDropdown(id) {
        if (this.state.categoryDrop === id) {
            this.setState({ categoryDrop: null });
            return;
        }
        this.setState({ categoryDrop: id });
        console.log(this.state.categoryDrop);
    }

    render() {
    return (
      <List
        removeClippedSubviews={false}
        bounces={false}
        dataArray={this.props.datas}
        renderRow={item =>
          <View>
            <ListItem
              onPress={() =>  this.categoryDropdown(item.id)}
              style={{ marginLeft: 0, paddingLeft: 10 }}
            >
              <Body>
                <Text style={styles.listHeading}>
                  {item.value}
                </Text>
              </Body>
              <Right>
                <Icon
                  style={styles.listIconHeading}
                  name={
                    item.id === this.state.categoryDrop
                      ? "ios-arrow-up"
                      : "ios-arrow-down"
                  }
                />
              </Right>
            </ListItem>
            {this.state.categoryDrop === item.id &&
              <List
                removeClippedSubviews={false}
                bounces={false}
                dataArray={item.sublist}
                renderRow={sublistItem =>
                  <ListItem
                    icon
                    style={styles.listDropItems}
                    onPress={() =>
                      this.props.navigation.navigate("ProductList")}
                  >
                    <Body>
                      <Text style={styles.listDropText}>
                        {sublistItem.value}
                      </Text>
                    </Body>
                    <Right>
                      <Icon style={styles.listIcon} name="ios-arrow-forward" />
                    </Right>
                  </ListItem>}
              />}
          </View>}
      />
    );
  }
}

export default ListDropdown;

Parent screen Code

import React, { Component } from "react";
import { ScrollView } from "react-native";
import {
  View,
  Text,
  Container,
  List,
  ListItem,
  Content,
  Card,
  CardItem,
  Left,
  Right,
  Button
} from "native-base";
import MyFooter from "../../components/Footer";
import BannerSlider from "../../components/BannerSlider/index.js";
import ListDropdown from "../../components/ListDropdown";
import ThemeHeader from "../../components/Header/index.js";
import { observer, inject } from "mobx-react/native";
import styles from "./styles.js";
import data from "../HomePage/data";

@inject("view.app", "domain.user", "app", "routerActions")
@observer
class Category extends Component {
  constructor(props) {
    super(props);
    this.state = {
      categoryDrop: null
    };
  }
  categoryDropdown(id) {

      if (this.state.categoryDrop === id) {
      this.setState({ categoryDrop: null });
      this.setState({ arrowDirection: "ios-arrow-dropdown-outline" });
      return;
    }
    this.setState({ categoryDrop: id });
  }
  render() {
    const navigation = this.props.navigation;
    var ListDropdownData = [
      {
          id: 275,
          value: "Fitness",
          sublist: [{id: 131, value: "Treadmill"}, {id: 132, value: "Crosstrainer"}, {id: 134, value: "Rowing"}, {id: 134, value: "Rowing"},  ]
      },
      {
          id: 125,
          value: "Swimming",
          sublist: [{id: 138, value: "Swimwear"}, {id: 139, value: "Goggles"}, {id: 141, value: "Swimming Accessories"} ]
      },
      {
          id: 126,
          value: "Badminton",
          sublist: [{id: 138, value: "Swimwear"}, {id: 139, value: "Goggles"}, {id: 325, value: "Badminton Apparel"} ],
      },
      {
          id: 4,
          value: "Gitar",
          sublist: [{id: 158, value: "Amplifier"}, {id: 184, value: "Gitar Elektrik"}, {id: 194, value: "Gitar Akustik"} ]
      },
    ];
    return (
      <Container>
        <ThemeHeader PageTitle="CATEGORIES" IconRight="ios-search" />
        <Content showsVerticalScrollIndicator={false}>
          <Card>
            <CardItem style={{ padding: 0 }}>
              <ListDropdown navigation={navigation} datas={ListDropdownData} />
            </CardItem>
          </Card>
          <Card>
            <CardItem
              style={{ paddingTop: 0, paddingLeft: 0, paddingBottom: 0 }}
            >
              <Left>
                <Text style={{ fontSize: 14, color: "#696d79" }}>
                  RECENTLY VIEWED
                </Text>
              </Left>
              <Right>
                <Button small transparent>
                  <Text style={styles.clearAll}>CLEAR ALL</Text>
                </Button>
              </Right>
            </CardItem>
            <CardItem style={{ paddingHorizontal: 5, paddingVertical: 0 }}>
              <ScrollView
                directionalLockEnabled={false}
                horizontal={true}
                showsHorizontalScrollIndicator={false}
              >
                <List
                  removeClippedSubviews={false}
                  bounces={false}
                  contentContainerStyle={{ flex: 1, flexDirection: "row" }}
                  dataArray={data}
                  renderRow={item =>
                    <BannerSlider
                      imageStyle={{
                        height: 100,
                        width: 170,
                        resizeMode: "stretch"
                      }}
                      onPress={() => navigation.navigate("ProductList")}
                      bannerImageText={item.bannerImageText}
                      bannerImageSource={item.bannerImageSource}
                      bannerSmallText={item.bannerSmallText}
                      navigation={navigation}
                    />}
                />
              </ScrollView>
            </CardItem>
          </Card>
          <View style={{ alignItems: "center" }}>
            <ListItem noBorder>
              <Text style={styles.contactListItem}>Contact Us</Text>
            </ListItem>
            <ListItem noBorder>
              <Text style={styles.contactListItem}>FAQs</Text>
            </ListItem>
            <ListItem noBorder>
              <Text style={styles.contactListItem}>About Us</Text>
            </ListItem>
            <ListItem noBorder>
              <Text style={styles.contactListItem}>Terms of use</Text>
            </ListItem>
          </View>
        </Content>
        <MyFooter navigation={navigation} selected={"categories"} />
      </Container>
    );
  }
}
export default Category;

The list itself is rendered, the problem is the sub array won't appear after the we pressed the button. I tried to remove the state categoryDrop check on the list, and the data are rendered.

also checked the function did work and the state changed. Why does the list won't dropdown when i used the props?

It seems like you are rendering the list before the api response, so your list is already render before you have array of data and after api response your view is not render again. You can set a if condition before your list, it won't execute until you receive data from api.

if(this.props.arr && this.props.arr.length>0){
    <List />
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM