如果可见性支持者重新渲染,是否可以防止模式被隐藏?

时间:2019-11-13 16:32:53

标签: reactjs react-native

我有一个包含四个不同项目列表的组件。根据日期将项目放置在列表中。当用户单击按钮以更改该项目的日期时,将出现一个带有日期选择器的模式(该项目的dateModalVisbility道具切换为true)。这可以按预期工作,但是如果项目的日期更改导致其切换列表,则日期选择器模式会消失,而道具不会切换为false。然后,当您单击按钮重新打开时,它将切换为false,然后再次按下将切换回true,然后重新打开。我相信这是由于该项目在切换到其他列表时重新呈现所致。

我想强制模式保持打开状态,即使它切换列表也是如此。我尝试过在其他任何渲染之前创建不同的list函数,但这并不能解决问题。我没有主意,不确定是否可以做到这一点。

我的平面列表(this.props.todos来自redux):

<FlatList
  data={_.sortBy(this.props.todos, item => {
    return item.date;
  })}
  extraData={this.props.todos}
  keyExtractor={item => item.id.toString()}
  renderItem={({ item }) => {
    if (moment().isSame(item.date, 'day')) {
      return (
        <TodoItem
          todoItem={item}
          deleteTodo={() => this.props.removeTodo(item)}
        />
      );
    }
  }}
/>
<View style={styles.headerViewStyle}>
  <Text style={styles.headerTextStyle}>Tomorrow</Text>
</View>

<FlatList
  data={_.sortBy(this.props.todos, item => {
    return item.date;
  })}
  extraData={this.props.todos}
  keyExtractor={item => item.id.toString()}
  renderItem={({ item }) => {
    if (
      moment()
        .add(1, 'day')
        .isSame(item.date, 'day')
    ) {
      return (
        <TodoItem
          todoItem={item}
          deleteTodo={() => this.props.removeTodo(item)}
        />
      );
    }
  }}
/>

<View style={styles.headerViewStyle}>
  <Text style={styles.headerTextStyle}>Upcoming</Text>
</View>

<FlatList
  data={_.sortBy(this.props.todos, item => {
    return item.date;
  })}
  extraData={this.props.todos}
  keyExtractor={item => item.id.toString()}
  renderItem={({ item }) => {
    if (
      moment()
        .add(1, 'day')
        .isBefore(item.date, 'day')
    ) {
      return (
        <TodoItem
          todoItem={item}
          deleteTodo={() => this.props.removeTodo(item)}
        />
      );
    }
  }}
/>

<View style={styles.headerViewStyle}>
  <Text style={styles.headerTextStyle}>Sometime</Text>
</View>

<FlatList
  data={_.sortBy(this.props.todos, item => {
    return item.date;
  })}
  extraData={this.props.todos}
  keyExtractor={item => item.id.toString()}
  renderItem={({ item }) => {
    if (moment().isAfter(item.date, 'day') || item.date === null) {
      return (
        <TodoItem
          todoItem={item}
          deleteTodo={() => this.props.removeTodo(item)}
        />
      );
    }
  }}
/>

todoItem组件:

class TodoItem extends Component {
  render() {
    const todoItem = this.props.todoItem;

    return (
      <View>
        <ItemSwipeRow item={todoItem} completeItem={this.props.deleteTodo}>
          <TouchableHighlight
            onPress={() => this.props.toggleItemMenu(todoItem)}
            underlayColor={null}>
            <ListItem
              containerStyle={styles.todoItem}
              contentContainerStyle={styles.contentStyle}
              title={todoItem.text}
              titleStyle={{ color: '#FCEFEF', fontSize: 16 }}
              rightElement={todoItem.date ? this.renderDate.bind(this)() : null}
            />
          </TouchableHighlight>
        </ItemSwipeRow>
        {todoItem.itemMenuToggled ? <ItemMenuBar item={todoItem} /> : null}
        {this.props.reminderToggleActive && todoItem.date ? (
          <ReminderToggleButtons item={todoItem} />
        ) : null}
        <NotesModal item={todoItem} />
        {todoItem.dateModalVisible ? <DatePickerModal item={todoItem} /> : null}
      </View> //this line above is responsible for displaying the date picker modal
    );
  }
}

和DatePickerModal:

class DatePickerModal extends Component {
  render() {
    return (
      <Modal transparent animationType="fade" visible>
        <View style={styles.containerStyle}>
          <View style={styles.modalContainer}>
            <View style={{ justifyContent: 'flex-end', flexDirection: 'row' }}>
              <View style={{ padding: 5 }}>
                <Feather
                  name="x-square"
                  size={35}
                  color={'#db5461'}
                  onPress={() => this.props.toggleDateModal(this.props.item)}
                />
              </View>
            </View>
            <View style={{ padding: 5 }}>
              {Platform.OS === 'ios' ? (
                <IosDatePicker item={this.props.item} />
              ) : (
                <AndroidDatePicker />
              )}
            </View>
          </View>
        </View>
      </Modal>
    );
  }
}

我可以提供打开该项目的操作和按钮,但我认为这不是问题的根源。按钮/动作在正确地完成工作。

1 个答案:

答案 0 :(得分:0)

我会重新安排您使用模态的方式。代替每个组件具有模态,将一个模态添加到顶层组件,然后使用props设置选定的项。像这样的东西:

export default class TopComponent extends React.Component {

  this.state = {
    selectedItem: null,
    modalvisible: false,
  }
  
  render = () => {
    return (
    <FlatList renderItem={({item, key} => (<MyItem onItemSelected={item => this.setState({ selectedItem: item, modalVisible: true}))} />} />
    <Modal visible={this.state.modalVisible}>
      <Text>this.state.selectedItem</Text>
    </Modal>
  }

}

以下是显示更多详细信息的快速代码框:https://codesandbox.io/s/react-native-6518p