React Native - 如何 select 所有项目并在单击 selected 项目之一时再次取消 select

React Native - How to select all items and unselect again when one of selected items is clicked

我一直在尝试制作 Select All 按钮。单击其中一个选定的项目,我希望取消选择 Select All 按钮,但我的代码没有显示这个。当我点击 Select All 按钮时,它会选择所有,但其余项目什么都不做。

授权加入:

import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import colors from '#common/colors';
import CheckBoxWithoutSquare from '#components/Box/CheckBoxWithoutSquare';


const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    marginTop: 100,
  },
  displayNone: {
    display: 'none',
  },
  joinForm: {
    height: 440,
    flexGrow: 0,
  },
  textStyle: {
    fontSize: 13,
    fontWeight: 'normal',
    color: colors.black,
  },
  checkContainer: {
    marginHorizontal: 15,
  },
  checkBox: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  checkText: {
    marginLeft: 10,
    fontSize: 13,
    fontWeight: 'normal',
    color: colors.black,
  },
  underline: {
    textDecorationLine: 'underline',
    fontSize: 13,
    fontWeight: 'normal',
    color: colors.black,
  },
  btnStyle: {
    backgroundColor: colors.iris,
    height: 50,
    position: 'absolute',
  },
});

const agreements = [
  {
    content: 'test1',
    checked: false,
  },
  {
    content: 'test2',
    checked: false,
  },
];

const AuthJoin = (props) => {
  const [data, setData] = useState(agreements);

  const [isChecked, setIsChecked] = useState(true);
  const checkAll = () => {
    let temp = data.map((item) => {
      return { ...item, checked: true };
    });
    setData(temp);

    console.log(temp);
  };
  const checkOne = (newValue, index) => {
    let temp = data.map((item, i) => {
      return index === i ? { ...item, checked: newValue } : item;
    });
    setData(temp);
    setIsChecked(!isChecked);
  };

  return (
    <>
      <View style={[styles.container]}>
        <View style={[styles.checkContainer]}>
          <View style={[styles.checkBox, { marginBottom: 20 }]}>
            <CheckBox onPress={checkAll} size={20} />
            <Text style={[styles.checkText]}>Select All</Text>
          </View>

          {data.map((item, index) => (
            <View
              style={[styles.checkBox, { justifyContent: 'space-between' }]}
            >
              <View style={[styles.checkBox, { marginBottom: 10 }]}>
                <CheckBoxWithoutSquare
                  // isChecked={!isChecked}
                  onPress={(newValue) => checkOne(newValue, index)}
                />
                <Text style={[styles.checkText]}>{item.content}</Text>
              </View>
              <TouchableOpacity>
                <Text style={[styles.underline]}>보기</Text>
              </TouchableOpacity>
            </View>
          ))}

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

export default AuthJoin;

CheckBoxWithoutSquare :

const styles = StyleSheet.create({
  container: {
    width: 20,
    height: 20,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

const CheckBoxWithoutSquare = ({ isChecked, onPress, size = 20 }) => {
  return (
    <TouchableOpacity style={[styles.container]} onPress={onPress}>
      <Image
        style={{ width: 15, height: 15 }}
        source={isChecked ? assets.icon_check_on : assets.child_checked_off}
      />
    </TouchableOpacity>
  );
};

复选框:

const CheckBox = ({ isChecked, onPress, size = 15 }) => {
  return (
    <TouchableOpacity style={{ width: size, height: size }} onPress={onPress}>
      <Image
        style={{ width: size, height: size }}
        source={isChecked ? assets.icon_check_on : assets.checked_off}
      />
    </TouchableOpacity>
  );
};

CheckBox.propTypes = {};

export default CheckBox;

我已经用谷歌搜索了,但还是不明白。我觉得我应该用 array 做 useState ,然后就没有再进一步了。我该怎么办?

这是工作示例:Expo Snack

import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Image } from 'react-native';
import { AntDesign } from '@expo/vector-icons';

const CheckBox = ({ isChecked, onPress, size = 15 }) => {
  return (
    <TouchableOpacity style={{ width: size, height: size }} onPress={onPress}>
      {isChecked ? (
        <Image
          style={{ width: size, height: size }}
          source={require('./assets/green.png')}
        />
      ) : (
        <Image
          style={{ width: size, height: size }}
          source={require('./assets/grey.png')}
        />
      )}
    </TouchableOpacity>
  );
};

const CheckBoxWithoutSquare = ({ isChecked, onPress, size = 20 }) => {
  return (
    <TouchableOpacity style={[styles.container]} onPress={onPress}>
      {isChecked ? (
        <Image
          style={{ width: size, height: size }}
          source={require('./assets/green.png')}
        />
      ) : (
        <Image
          style={{ width: size, height: size }}
          source={require('./assets/grey.png')}
        />
      )}
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    marginTop: 100,
  },

  checkContainer: {
    marginHorizontal: 15,
  },
  checkBox: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  checkText: {
    marginLeft: 10,
    fontSize: 13,
    fontWeight: 'normal',
    color: 'black',
  },
  underline: {
    textDecorationLine: 'underline',
    fontSize: 13,
    fontWeight: 'normal',
    color: 'black',
  },
});

const agreements = [
  {
    content: 'test1',
    checked: false,
  },
  {
    content: 'test2',
    checked: false,
  },
];

const AuthJoin = (props) => {
  const [data, setData] = useState(agreements);
  const [isChecked, setIsChecked] = useState(true);
  const [selectAll, setSelectAll] = useState(
    data.filter((item) => item.checked).length === data.length
  );
  const checkAll = () => {
    let newValue = data.filter((item) => item.checked).length === data.length;
    let temp = data.map((item) => {
      return { ...item, checked: !newValue };
    });
    setData(temp);

    console.log(temp);
  };
  const checkOne = (newValue, index) => {
    let temp = data.map((item, i) => {
      return index === i ? { ...item, checked: newValue } : item;
    });
    setData(temp);
    setIsChecked(!isChecked);
  };

  return (
    <>
      <View style={[styles.container]}>
        <View style={[styles.checkContainer]}>
          <View style={[styles.checkBox, { marginBottom: 20 }]}>
            <CheckBox
              isChecked={
                data.filter((item) => item.checked).length === data.length
              }
              onPress={checkAll}
              size={20}
            />
            <Text style={[styles.checkText]}>Select All</Text>
          </View>

          {data.map((item, index) => (
            <View
              style={[styles.checkBox, { justifyContent: 'space-between' }]}>
              <View style={[styles.checkBox, { marginBottom: 10 }]}>
                <CheckBoxWithoutSquare
                  isChecked={item.checked}
                  onPress={() => checkOne(!item.checked, index)}
                />
                <Text style={[styles.checkText]}>{item.content}</Text>
              </View>
              <TouchableOpacity>
                <Text style={[styles.underline]}>보기</Text>
              </TouchableOpacity>
            </View>
          ))}
        </View>
      </View>
    </>
  );
};

export default AuthJoin;