React Native - Changing States in an Array of another file

693 Views Asked by At

Hey Everyone :) This is my first post here, hope I am doing everything correctly!

I am currently working on a school project and using react-native for some weeks now.

My Problem:

I have the file data.js:

const cardOne_1 = require("../images/Vergleiche/Eisbär.jpg");
const cardTwo_1 = require("../images/Vergleiche/Android.jpg");
const cardThree_1 = require("../images/Vergleiche/Han_Solo_Alt.jpg");

const cardOne_2 = require("../images/Vergleiche/Gorilla.jpg");
const cardTwo_2 = require("../images/Vergleiche/Apple.jpg");
const cardThree_2 = require("../images/Vergleiche/Han_Solo_Jung.jpg");


 export default[
  {
    image: cardOne_1,
    image2: cardOne_2,
    text: '53%',
    text2: '47%',
    title: 'Icebear vs Gorilla',
    check: false,

  },
  {
    image: cardTwo_1,
    image2: cardTwo_2,
    text: '19%',
    text2: '81%',
    title: 'Android vs IOS',
    check: true,

  },
  {
    image: cardThree_1,
    image2: cardThree_2,
    text: '70%',
    text2: '30%',
    title: 'Han Solo',
    check: false,
  },
];

My Homescreen contains two of these Deckswipers (For better clarity I will show here only the code for the first one), which are used to compare two images: Homescreen - With two DeckSwiper

import data from '../Data.js';

export default class SwipeCards2 extends Component {
  _onSwipeLeft() {
    this._deckSwiper1._root.swipeLeft();
    this._deckSwiper2._root.swipeRight();
  }

  _onSwipeRight() {
    this._deckSwiper2._root.swipeLeft();
    this._deckSwiper1._root.swipeRight();
  }
  render() {
    return (
      <Container style={{ backgroundColor: '#ffffff' }}>
        <View>
          <DeckSwiper
            ref={mr => (this._deckSwiper1 = mr)}
            dataSource={data}
            onSwipeRight={() => this._deckSwiper2._root.swipeLeft()}
            onSwipeLeft={() => this._deckSwiper2._root.swipeRight()}
            looping={true}
            renderEmpty={() => (
              <View style={{ alignSelf: 'center' }}>
                <Text>Das war´s!</Text>
              </View>
            )}
            renderItem={item => (
              <Card
                style={{
                  elevation: 3,
                  height: 335,
                  justifyContent: 'center',
                  width: Dimensions.get('window').width + 1,
                  marginLeft: -1,
                  marginTop: 0,
                }}>

                <TouchableWithoutFeedback onPress={() => this._onSwipeRight()}>

                  <CardItem cardBody style={{ alignItems: 'center' }}>
                    <Image
                      style={{
                        resizeMode: 'cover',
                        flex: 1,
                        height: 335,
                      }}
                      source={item.image}
                    />
                  </CardItem>
                </TouchableWithoutFeedback>

              </Card>
            )}
          />

        </View>
      </Container>
    );
  }
}

I want to set the state "check" in data.js to true, everytime the user does swipe to the right.

A Third Screen renders a List component, which should show the previous made decisions of the user. This list is based on "check" of data.js.

Screen 3 - List of all the decisions

I tried for almost three days and can not find any good solution!

Do you have any suggestions how to achieve this?

Thanks :)

1

There are 1 best solutions below

1
bennygenel On

I'm not sure how things work with this DeckSwiper component but since you are importing a static data, if you need to change the data you need to clone it and then change it. Assigning data clone to a state variable and then giving it to the component will reflect the changes to the component.

To change a property on a specific object in your array you also need an unique identifier like an ID or similar.

Example

import data from '../Data.js';

export default class SwipeCards2 extends Component {
  constructor(props) {
    super(props);
    // clone the static data to state
    this.state = {
      data: [...data]
    }
  }
  changingCheckFunction(obejctsUniqueId) {
    this.setState((prevState) => {
       // find the object's id
      const itemIndex = prevState.data.findIndex(x => x.id == obejctsUniqueId);
      // copy the item and assign the new checked value
      const newItem = Object.assign({}, prevState.data[itemIndex], { checked: !prevState.data[itemIndex]}); 
      // copy the previous data array
      const newData = [...prevState.data];
      // set the newItem to newData
      newData[itemIndex] = newItem;
      // return the new data value to set state
      return { data: newData };
    });
  }
  _onSwipeLeft() {
    this._deckSwiper1._root.swipeLeft();
    this._deckSwiper2._root.swipeRight();
  }

  _onSwipeRight() {
    this._deckSwiper2._root.swipeLeft();
    this._deckSwiper1._root.swipeRight();
  }
  render() {
    return (
      <Container style={{ backgroundColor: '#ffffff' }}>
        <View>
          <DeckSwiper
            ref={mr => (this._deckSwiper1 = mr)}
            dataSource={this.state.data}
            onSwipeRight={() => this._deckSwiper2._root.swipeLeft()}
            onSwipeLeft={() => this._deckSwiper2._root.swipeRight()}
            looping={true}
            renderEmpty={() => (
              <View style={{ alignSelf: 'center' }}>
                <Text>Das war´s!</Text>
              </View>
            )}
            renderItem={item => (
              <Card
                style={{
                  elevation: 3,
                  height: 335,
                  justifyContent: 'center',
                  width: Dimensions.get('window').width + 1,
                  marginLeft: -1,
                  marginTop: 0,
                }}>

                <TouchableWithoutFeedback onPress={() => this._onSwipeRight()}>

                  <CardItem cardBody style={{ alignItems: 'center' }}>
                    <Image
                      style={{
                        resizeMode: 'cover',
                        flex: 1,
                        height: 335,
                      }}
                      source={item.image}
                    />
                  </CardItem>
                </TouchableWithoutFeedback>

              </Card>
            )}
          />

        </View>
      </Container>
    );
  }
}