Как обновить / обновить расширяемый вид списка в реагировать родной - PullRequest
0 голосов
/ 24 июня 2019

Я занимаюсь разработкой приложения для Android, использующего реагирующий натив, который включает страницу корзины.Я использовал [ExpandableListView]: https://aboutreact.com/expandable-list-view/), чтобы показать элементы, сгруппированные по категориям.Каждый элемент имеет кнопки «+» и «-» для изменения количества.Вот мой код:

DetailScreen.js:

    import React, { Component } from 'react';
    import { LayoutAnimation, StyleSheet, TouchableOpacity, View, Text, ScrollView, UIManager, Platform, TextInput, KeyboardAvoidingView, ImageBackground, Picker, Image, Linking, Alert, } from 'react-native';

 export default class DetailsScreen extends Component 
 {

    static navigationOptions = {
      title: 'Details',
      header: null,
    }

    constructor(props) 
    {
      super(props);
      if (Platform.OS === 'android') {
         UIManager.setLayoutAnimationEnabledExperimental(true);
      }
     this.state = 
      {
         listDataSource: [
         {
          isExpanded: false,
          category_name: 'Item 1',
          subcategory: [{ id: 1, val: 'Sub Cat 1', count:'0' }, { id: 3, val: 'Sub Cat 3', count:'0' }],
         },
         {
          isExpanded: false,
          category_name: 'Item 2',
          subcategory: [{ id: 4, val: 'Sub Cat 4', count:'0' }, { id: 5, val: 'Sub Cat 5', count:'0' }],
         }],       
     };
   }

  updateLayout = index => {

  LayoutAnimation.configureNext
  (LayoutAnimation.Presets.easeInEaseOut);
      const array = [...this.state.listDataSource];
      array[index]['isExpanded'] = !array[index]['isExpanded'];
      this.setState(() => {
          return {
              listDataSource: array,
          };
      });
  };

  updateSalonData = newData =>
  {
      console.log('new Data: '  + JSON.stringify(newData));             
       var tempData = [...this.state.listDataSource];
      let index = tempData.findIndex(x => x.category_name === newData.category_name);
      tempData[index] = newData;          
      this.setState(() => {
          return {
              listDataSource: tempData,
          };
      });              
  };

  render() {
       return (
      <View style={{ marginStart: 10, marginEnd: 10, marginTop: 5, borderBottomWidth: 0.5 }}></View>
          <Text style={styles.topHeading}>Services</Text>

          <ScrollView enabled keyboardShouldPersistTaps={'handled'} showsVerticalScrollIndicator={false} contentContainerStyle={{ flexGrow: 1, }}>
              {this.state.listDataSource.map((item, key) => (
                    <ExpandableItemComponent
                        key={item.category_name}
                        onClickFunction={this.updateLayout.bind(this, key)}
                        item={item}
                        updateSalonData = {this.updateSalonData.bind(this, item)}/>
                            ))}
           </ScrollView>
        </View>
     );
   }
}

ExpandableItemComponent.js:

 import React, { Component } from 'react';
 import { LayoutAnimation, StyleSheet, View, Text, ScrollView, UIManager, TouchableOpacity, Platform, } from 'react-native';

   export default class ExpandableItemComponent extends Component {
   //Custom Component for the Expandable List
    constructor(props) {
     super(props);
      console.log('props: ' + JSON.stringify(props.item));     
     this.state = {
       layoutHeight: 0,
       dataSource:props.item,
   };
 }  

    componentWillReceiveProps(nextProps) {   
      console.log('componentWillReceiveProps'); 
      if (nextProps.item.isExpanded) {
      this.setState(() => {
        return {
          layoutHeight: null,
       };
    });
   } else {
    this.setState(() => {
      return {
        layoutHeight: 0,
      };
    });
 }
console.log('next Item: ' + JSON.stringify(nextProps.item) + "\n"); 
this.setState(() => {
  return {
    dataSource: nextProps.item,
      };
    });
  }
  shouldComponentUpdate(nextProps, nextState) {
     if (this.state.layoutHeight !== nextState.layoutHeight) {
       return true;
      }
     return false;
  }

   setItemCount = (id) =>
    {        
      const tempItem = this.props.item;
      const data = this.props.item.subcategory;
      const index = data.findIndex(x => x.id === id);
      // console.log('pricing Index: ' + index);
      if (index !== -1) {
        data[index]["cartCount"] = 10; 
        tempItem.subcategory = data;               
        this.props.updateSalonData(tempItem);
    } 
 }

  render() {

return (
  <View>

    {/*Header of the Expandable List Item*/}
    <TouchableOpacity
      activeOpacity={0.8}
      onPress={this.props.onClickFunction}
      style={styles.header}>
      <Text style={styles.headerText}>{this.state.dataSource.category_name}</Text>
    </TouchableOpacity>
    <View
      style={{
        height: this.state.layoutHeight,
        overflow: 'hidden',
      }}>
      {/*Content under the header of the Expandable List Item*/}
      {this.state.dataSource.subcategory.map((item, key) => (
        <TouchableOpacity
          key={key}
          style={styles.content}
          onPress={() => alert('Id: ' + item.id + ' val: ' + item.val)}>
          <View style={{ flex: 1, flexDirection: 'row', alignContent: 'center', justifyContent: 'space-between'}}>
            <Text style={styles.text}>{item.val}</Text>

            <View style={{ flexDirection: 'row', alignSelf: 'center', }}>
              <Text style={styles.text}>{item.val}</Text>
              <View style={{ height: 25, width: 75, flexDirection: 'row', borderRadius: 15, borderWidth: 1, alignSelf: 'center', justifyContent: 'space-evenly', borderColor: 'orange', overflow: 'hidden' }}>

                <View style={{ alignContent: 'center', justifyContent: 'center' }}>
                  <Text onPress={()=>{this.setItemCount(item.id)}} style={{ width: 25, height: 25, fontSize: 12, color: 'orange', fontWeight: 'bold', textAlign: 'center', textAlignVertical: 'center' }}>+</Text>
                </View>
                <View style={{ borderWidth: 1, borderColor: 'orange', backgroundColor: 'orange', alignContent: 'center', justifyContent: 'center' }}>
                  <Text style={{ width: 25, height: 25, fontSize: 12, color: 'white', fontWeight: 'bold', textAlign: 'center', textAlignVertical: 'center' }}>{item.cartCount}</Text>
                </View>
                <View style={{ alignContent: 'center', justifyContent: 'center' }}>
                  <Text style={{ width: 25, height: 25, fontSize: 12, color: 'orange', fontWeight: 'bold', textAlign: 'center', textAlignVertical: 'center' }}>-</Text>
                </View>

              </View>
            </View>
          </View>

          {/* <View style={styles.separator} /> */}
        </TouchableOpacity>
      ))}
    </View>
    <View style={styles.separator} />
  </View>
);
 }
 }

Сейчаспроблема в том, что когда я нажимаю кнопку «+», счетчик фактически увеличивается в коде, но не обновляется в пользовательском интерфейсе.Но когда я сверну и разверну тот же элемент, теперь значение обновляется.Кто-то может подсказать мне обновить счетчик, как только я нажму кнопку +.

1 Ответ

0 голосов
/ 24 июня 2019

Можете ли вы заменить ваш this.state.dataSource для направления this.props.updateSalonData на ExpandableItemComponent.js

Если обновление было выполнено в родительском классе, оно автоматически обновится в дочернем классе, если это так.

например:

...
{this.props.updateSalonData.subcategory.map((item, key) => (

....

вот так.

...