如何将商品从单位列表传递给孙子?

时间:2019-11-05 11:22:38

标签: reactjs react-native

我有一个物品清单。当我将项目传递给renderItem组件时,一切工作正常。然后,当我将完全相同的项目传递给负责渲染项目的组件中的孩子时,就会出现问题。

通常它可以正常工作,但是如果有多个列表项,并且上面的列表项被删除,它将失去适当的功能并变得非常有问题。我认为问题是因为无论出于什么原因,孙子仍然认为该项目是该项目的索引,而不是进入该索引的是另一个项目。

我的单位列表:

<FlatList
            data={this.props.items}
            extraData={this.props.items}
            keyExtractor={(item, index) => index.toString()}
            renderItem={({ item }) => {
              return (
                <TodoItem
                  todoItem={item}
                />
              );
            }}
          />

然后在TodoItem中,这就是我将项目传递给孙子的方式:

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

    return (
        <View>
          <ItemSwipeRow
            item={todoItem}
            completeItem={this.props.deleteTodo}
          >

然后在itemSwipeRow中,这就是我接收道具的方式

import React, { Component } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import { Ionicons, MaterialCommunityIcons } from '@expo/vector-icons';
import { connect } from 'react-redux';
import { openNotesModal, openDateModal } from '../actions';

const AnimatedIcon = Animated.createAnimatedComponent(Ionicons);

class ItemSwipeRow extends Component {
  constructor(props) {
    super(props);
    this.item = props.item;
  }

  renderLeftActions = (progress, dragX) => {
    const trans = dragX.interpolate({
      inputRange: [0, 50, 100, 101],
      outputRange: [-20, 0, 0, 1],
    });
    return (
      <RectButton style={styles.leftAction}>
        <AnimatedIcon
          name='md-checkmark'
          color='#28313b'
          size={45}
          style={[
            styles.actionText,
            {
              transform: [{ translateX: trans }],
            },
          ]}
        />
      </RectButton>
    );
  };

  renderRightAction = (action, name, color, x, progress) => {
    const trans = progress.interpolate({
      inputRange: [0, 1],
      outputRange: [x, 0],
    });
    const pressHandler = () => {
      action(this.item);
    };
    return (
      <Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
        <RectButton
          style={[styles.rightAction, { backgroundColor: color }]}
          onPress={pressHandler}
        >
          <MaterialCommunityIcons
            name={name}
            size={35}
            color='#28313b'
          />
        </RectButton>
      </Animated.View>
    );
  };

  renderRightActions = progress => (
    <View style={styles.rightSwipeButtons}>
      {this.renderRightAction(
        this.props.openDateModal, 'calendar', '#B8B8F3', 192, progress
      )}
      {this.renderRightAction(
        this.props.openNotesModal, 'pencil', '#F0A202', 128, progress
      )}
      {this.renderRightAction(
        this.props.openDateModal, 'bell', '#db5461', 64, progress
      )}
    </View>
  );

  updateRef = ref => {
    this.currItem = ref;
  };
  close = () => {
    if (this.currItem !== null) { this.currItem.close(); }
  };

  onSwipeableLeftOpen = () => {
    this.props.completeItem();
    this.close();
  }

  onSwipeableRightWillOpen = () => {
    console.log(this.item.text); //tried passing in item here but didn't 
  } //work, instead of console logging on call it did every item @ start
    // then none when it was suppose to log it.
  render() {
    const { children } = this.props;
    const { item } = this.props;
    return (
      <Swipeable
        ref={this.updateRef}
        friction={2}
        leftThreshold={70}
        rightThreshold={40}
        renderLeftActions={this.renderLeftActions}
        renderRightActions={this.renderRightActions}
        onSwipeableLeftOpen={this.onSwipeableLeftOpen}
        onSwipeableRightWillOpen={this.onSwipeableRightWillOpen}
      >
        {children}
      </Swipeable>
    );
  }
}

const styles = StyleSheet.create({
  leftAction: {
    flex: 1,
    backgroundColor: '#82ff9e',
    justifyContent: 'center',
  },
  rightAction: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
  },
  rightSwipeButtons: {
    width: 192,
    flexDirection: 'row'
  }
});


export default connect(null, { openNotesModal, openDateModal })(ItemSwipeRow);

我的控制台日志证明并非总是呈现正确的项目。删除该项目可以正常进行,但是,如果删除了某个项目,并且该项目下有某物,则该项目下的项目会假定该项目是刚刚删除的项目。

任何帮助,我们将不胜感激,如果需要,我可以提供更多代码。

删除项目的代码:

action that's sent on left swipe–

export const removeTodo = (item) => {
  return {
    type: REMOVE_TODO,
    id: item.id
  };
};

reducer action goes to–

case REMOVE_TODO: {
      const newList = state.todos.filter(item => item.id !== action.id);
      for (let i = 0, newId = 0; i < newList.length; i++, newId++) {
        newList[i].id = newId;
      }
      return {
      ...state,
      todos: newList
      };
    }

1 个答案:

答案 0 :(得分:0)

您可以使用解构分配来复制对象,而不是引用同一对象:

const { todoItem } = this.props

更多阅读:https://medium.com/@junshengpierre/javascript-primitive-values-object-references-361cfc1cbfb0