简体   繁体   English

React 原生单选组件

[英]React native single selectable components

I am trying to achieve a simple single selectable item, as shown in the image below.我正在尝试实现一个简单的单个可选项目,如下图所示。

在此处输入图像描述

Right now, I have created an array of my data items and using .map to render the components because there are only 3-4 items max, now I want to select only a single item and change the color on the basis, and if I select any other item, it should unselect all the other items but not the current single selected item/component.现在,我创建了一个数据项数组并使用.map渲染组件,因为最多只有 3-4 个项目,现在我只想 select 一个项目并在基础上更改颜色,如果我select 任何其他项目,它应该取消选择所有其他项目,但不是当前单个选定的项目/组件。 I tried to do this but I am able to select all of them, obviously.我试图这样做,但显然我能够 select 所有这些。 Below is the code:下面是代码:

const items = [
  {
    id: 1,
    iconName: 'male',
    title: 'Male',
    name: 'male',
  },
  {
    id: 2,
    iconName: 'female',
    title: 'Female',
    name: 'female',
  },
  {
    id: 3,
    iconName: 'transgender',
    title: 'Others',
    name: 'others',
  },
];

const Component = ({dispatch, iconName, title, name}) => {
  const [isSelected, setIsSelected] = useState(false);
  return (
    <TouchableOpacity
      activeOpacity={0.6}
      style={
        isSelected
          ? [styles.selectable, {backgroundColor: 'green'}]
          : [styles.selectable, {backgroundColor: COLORS.PINK}]
      }
      onPress={() => {
        setIsSelected(!isSelected);
      }}>
      <View style={styles.row}>
        <Ionicon name={iconName} size={36} color="#fff" />
        <Text>{title}</Text>
      </View>
    </TouchableOpacity>
  );
};

const Gender = () => {

  return (
    <View>
      <View>
        <Text>Your Gender</Text>
        <View>
          {items.map(item => (
            <Component
              key={item.id}
              title={item.title}
              iconName={item.iconName}
            />
          ))}
        </View>
      </View>
    </View>
  );
};

All though I could solve this by using separate states for each button, so whenever one is selected/pressed, the other states should become false. All though I could solve this by using separate states for each button, so whenever one is selected/pressed, the other states should become false. But then I would have to render individual component without using the .map method which I find inefficient.但是我必须在不使用.map方法的情况下渲染单个组件,我认为这种方法效率低下。 Can someone provide any solution based on my current approach to this problem?有人可以根据我目前解决此问题的方法提供任何解决方案吗?

Thank you!谢谢!

Consider moving isSelected to the parent component, and instead of storing a booolean, store the selected item id.考虑将 isSelected 移动到父组件,而不是存储布尔值,而是存储选定的项目 id。 Pass the itemId, selectedId, setSelectedId (as a callback) to the child components and change the style check to:将 itemId、selectedId、setSelectedId(作为回调)传递给子组件并将样式检查更改为:

style={
        itemId === selectedId
          ? [styles.selectable, {backgroundColor: 'green'}]
          : [styles.selectable, {backgroundColor: COLORS.PINK}]
      }
      onPress={() => {
        setSelectedId(itemId);
      }}>

Now you can get rid of keeping track whether the item is selected in the component, and only worry about it in the context of the parent (as it should be).现在您可以摆脱跟踪是否在组件中选择了该项目,而只需在父级的上下文中担心它(应该如此)。


const Gender = () => {
  const [selectedId, setSelectedId] = useState(false);

  return (
    <View>
      <View>
        <Text>Your Gender</Text>
        <View>
          {items.map(item => (
            <Component
              key={item.id}
              itemId={item.id}
              selectedId={selectedId}
              setSelectedId={setSelectedId}
              title={item.title}
              iconName={item.iconName}
            />
          ))}
        </View>
      </View>
    </View>
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM