首页 > 解决方案 > 尝试执行 setState 时如何防止更新 redux 存储数据?

问题描述

我有一个编辑屏幕 B,列表数据来自我的 redux-store

列表数据数组,如:

[
  { title: 'test title 1', data: [{ ...otherParams, selected: false }, { ...otherParams, selected: false}]},
  { title: 'test title 2', data: [{ ...otherParams, selected: false }, { ...otherParams, selected: false}]}
]

selected我将我的 redux-store 数据放入状态,并在触发时更改状态数据onPress,但是当我离开 B 屏幕并重新进入 B 时,控制台记录我的屏幕数据,generalDevices并且sectionData已更改,但我检查了反应本机调试器以查看我的redux-store 数据,generalDevices还是原来的,不知道为什么。

import React, { useState, useEffect } from 'react';
import {
  View,
  Text,
  SectionList,
  StyleSheet,
  Image,
  TouchableOpacity
} from 'react-native';
import { CommonActions } from '@react-navigation/native';
import { useDispatch, useSelector } from 'react-redux';
import Container from 'components/View/Container';
import BackHeader from 'components/View/BackHeader';
import ListArrowItem from 'components/List/ListArrowItem';

import { checkHeaderTitle } from './Functions';

import { Translate } from 'assets/translations';

import BackIcon from 'assets/image/back.png';
import SelectIcon from 'assets/image/select.png';
import UnselectIcon from 'assets/image/unselect.png';

const SelectFavoriteScreen = ({ navigation, route }) => {
  const { title } = route.params;
  const { generalDevices } = useSelector((state) => state.DeviceRedux);

  const newArray = [...generalDevices];

  const [sectionData, setSectionData] = useState(newArray);
  const [, forceUpdate] = useState(0);

  useEffect(() => {
    console.log('enter B');
    return () => console.log('leave B')
  }, []);

  console.log('generalDevices', generalDevices); // I think the data should original equal with my redux-store, but it changes with sectionData
  console.log('sectionData', sectionData); // I change the data selected when user trigger onPress function

  const onItemPress = (item) => {
    const { selected } = item;

    if (selected) {
      item.selected = false;
    } else {
      item.selected = true;
    }

    forceUpdate((n) => !n);
  };

  const renderHeader = ({ section }) => {
    const { title } = section;

    return (
      <View
        style={{
          backgroundColor: '#f4f4f4',
          paddingLeft: 16,
          paddingBottom: 12,
          paddingTop: 30
        }}>
        <Text style={styles.nameText}>{title}</Text>
      </View>
    );
  };

  const renderSection = ({ item }) => {
    const { name, icon, selected } = item;

    const selectedIcon = selected ? SelectIcon : UnselectIcon;

    return (
      <TouchableOpacity
        onPress={() => onItemPress(item)}
        style={{
          backgroundColor: '#fff',
          flexDirection: 'row',
          paddingHorizontal: 16,
          paddingVertical: 12
        }}>
        <View style={{ flexDirection: 'row', alignItems: 'center' }}>
          <View style={styles.iconCircle}>
            <Image source={icon} style={{ width: '65%', height: '65%' }} />
          </View>
          <Text style={{ marginLeft: 8 }}>{name}</Text>
        </View>
        <View style={{ flex: 1, alignItems: 'flex-end' }}>
          <Image source={selectedIcon} style={{ width: 14, height: 14 }} />
        </View>
      </TouchableOpacity>
    );
  };

  return (
    <Container>
      <BackHeader
        leftImage={BackIcon}
        onLeftPress={() => navigation.pop()}
        centerTitle={checkHeaderTitle(title)}
        rightTitle={Translate.confirm}
        onRightPress={() => alert('Confirm')}
      />
      <SectionList
        style={{ backgroundColor: '#f4f4f4' }}
        renderSectionHeader={renderHeader}
        renderItem={renderSection}
        sections={sectionData}
        keyExtractor={(item, index) => index}
        ItemSeparatorComponent={() => (
          <View
            style={{
              backgroundColor: 'gray',
              height: StyleSheet.hairlineWidth,
              marginLeft: 16
            }}
          />
        )}
      />
    </Container>
  );
};
// '#ccbf85' : '#f4f4f4'
const styles = StyleSheet.create({
  nameText: {
    fontSize: 18,
    fontWeight: '400',
    color: '#3A3A3D',
    fontFamily: 'PingFang TC'
  },
  iconCircle: {
    borderRadius: 100,
    borderWidth: 2,
    borderColor: '#ccbf85',
    width: 48,
    height: 48,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

export default SelectFavoriteScreen;

标签: reactjsreact-nativereact-redux

解决方案


推荐阅读