You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native实现为派对对象单独添加用户的方法

解决方案:给已有派对添加用户

核心思路

要实现独立添加用户到指定派对的功能,需要新增选中派对的状态管理,并编写专门的添加用户逻辑,而非仅在创建派对时初始化用户列表。

具体修改步骤

1. 新增状态变量

在组件顶部添加状态,用于记录当前选中的派对ID:

const [selectedPartyId, setSelectedPartyId] = useState(null);

2. 编写添加用户的处理函数

创建handleAddUser函数,根据选中的派对ID,将新用户追加到对应派对的users数组中:

const handleAddUser = () => {
  if (!selectedPartyId || !userName.trim()) return;

  setParties(prevParties => 
    prevParties.map(party => {
      if (party.id === selectedPartyId) {
        // 生成唯一用户ID,用当前用户列表最大ID+1保证唯一性
        const newUserId = party.users.length > 0 ? Math.max(...party.users.map(u => u.id)) + 1 : 0;
        return {
          ...party,
          users: [...party.users, { id: newUserId, name: userName }]
        };
      }
      return party;
    })
  );
  setUser(""); // 清空输入框
};

3. 调整UI,添加选中和添加用户的交互

调整派对项的渲染

给每个派对项添加选中样式,并绑定选中事件:

{parties.map((item, index) => {
  const isSelected = item.id === selectedPartyId;
  return (
    <TouchableOpacity
      key={index}
      onPress={() => setSelectedPartyId(item.id)}
      style={[styles.partyItem, isSelected && styles.selectedParty]}
    >
      <Task name={item.partyName} description={item.description} date={item.date}></Task>
      <Text style={styles.userListTitle}>参与用户:</Text>
      {item.users.map((user, userIndex) => (
        <View key={userIndex} style={styles.userItem}>
          <Text>{user.name}</Text>
        </View>
      ))}
    </TouchableOpacity>
  );
})}

新增添加用户的专属区域

在页面底部添加用于给选中派对加用户的输入框和按钮:

{selectedPartyId && (
  <View style={styles.addUserSection}>
    <TextInput
      style={[styles.input, styles.userInput]}
      placeholder="输入要添加的用户名"
      value={userName}
      onChangeText={setUser}
    />
    <TouchableOpacity onPress={handleAddUser} style={styles.addWrapper}>
      <Text style={styles.addText}>添加用户</Text>
    </TouchableOpacity>
  </View>
)}

4. 补充样式(提升交互体验)

添加选中派对和用户列表的样式:

const styles = StyleSheet.create({
  // 原有样式保留,新增以下样式
  partyItem: {
    marginBottom: 15,
    padding: 15,
    borderWidth: 1,
    borderColor: '#eee',
    borderRadius: 8,
    backgroundColor: '#fff',
  },
  selectedParty: {
    borderColor: '#2196F3',
    backgroundColor: '#E3F2FD',
  },
  userListTitle: {
    fontSize: 16,
    fontWeight: '600',
    marginTop: 10,
    marginBottom: 5,
  },
  userItem: {
    fontSize: 14,
    paddingVertical: 2,
    paddingLeft: 10,
  },
  addUserSection: {
    position: 'absolute',
    bottom: 10,
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    paddingHorizontal: 10,
  },
  userInput: {
    flex: 1,
    marginBottom: 0,
  },
});

5. 优化创建派对逻辑(可选)

如果希望创建派对时可以不填初始用户,修改handleAddButtonClick中的用户初始化部分:

users: userName.trim() ? [{ id: 0, name: userName }] : []

完整修改后的代码

import React, { useState } from "react";
import {
  Platform,
  KeyboardAvoidingView,
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  ScrollView,
} from "react-native";

import Task from "./components/task";

export default function App() {
  const [partyTitle, setPartyName] = useState("");
  const [description, setDescription] = useState("");
  const [date, setDate] = useState("");
  const [userName, setUser] = useState("");
  const [selectedPartyId, setSelectedPartyId] = useState(null);

  const [parties, setParties] = useState([
    { 
      partyName: "Party 1", 
      description: "test", 
      id: 0,
      date:"12.01.2022",
      users:[{id:0, name:'John'}] 
    },
  ]);

  const handleAddButtonClick = () => {
    if (!partyTitle.trim()) return;
    setParties((prev) => [
      ...prev,
      {
        partyName: partyTitle,
        description: description,
        id: prev.length, // 用prev.length保证ID唯一
        date: date,
        users: userName.trim() ? [{ id: 0, name: userName }] : []
      },
    ]);
    setPartyName("");
    setDescription("");
    setDate("");
    setUser("");
  };

  const handleAddUser = () => {
    if (!selectedPartyId || !userName.trim()) return;

    setParties(prevParties => 
      prevParties.map(party => {
        if (party.id === selectedPartyId) {
          const newUserId = party.users.length > 0 ? Math.max(...party.users.map(u => u.id)) + 1 : 0;
          return {
            ...party,
            users: [...party.users, { id: newUserId, name: userName }]
          };
        }
        return party;
      })
    );
    setUser("");
  };

  return (
    <View style={styles.container}>
      <ScrollView
        contentContainerStyle={{ flexGrow: 1 }}
        keyboardShouldPersistTaps="handled"
      >
        <View style={styles.tasksWrapper}>
          <Text style={styles.sectionTitle}>Upcoming parties</Text>
          <View style={styles.items}>
            {parties.map((item, index) => {
              const isSelected = item.id === selectedPartyId;
              return (
                <TouchableOpacity
                  key={index}
                  onPress={() => setSelectedPartyId(item.id)}
                  style={[styles.partyItem, isSelected && styles.selectedParty]}
                >
                  <Task name={item.partyName} description={item.description} date={item.date}></Task>
                  <Text style={styles.userListTitle}>参与用户:</Text>
                  {item.users.map((user, userIndex) => (
                    <View key={userIndex} style={styles.userItem}>
                      <Text>{user.name}</Text>
                    </View>
                  ))}
                </TouchableOpacity>
              );
            })}
          </View>
        </View>
      </ScrollView>

      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        style={styles.writeTaskWrapper}
      >
        <View style={styles.createPartySection}>
          <TextInput
            style={styles.input}
            placeholder="输入派对名称"
            value={partyTitle}
            onChangeText={setPartyName}
          />
          <TextInput
            style={styles.input}
            placeholder="输入派对描述"
            value={description}
            onChangeText={setDescription}
          />
          <TextInput
            style={styles.input}
            placeholder="输入派对日期"
            value={date}
            onChangeText={setDate}
          />
          <TextInput
            style={styles.input}
            placeholder="初始用户(可选)"
            value={userName}
            onChangeText={setUser}
          />
        </View>

        <TouchableOpacity onPress={handleAddButtonClick}>
          <View style={styles.addWrapper}>
            <Text style={styles.addText}>创建派对</Text>
          </View>
        </TouchableOpacity>
      </KeyboardAvoidingView>

      {/* 添加用户区域 */}
      {selectedPartyId && (
        <View style={styles.addUserSection}>
          <TextInput
            style={[styles.input, styles.userInput]}
            placeholder="输入要添加的用户名"
            value={userName}
            onChangeText={setUser}
          />
          <TouchableOpacity onPress={handleAddUser} style={styles.addWrapper}>
            <Text style={styles.addText}>添加用户</Text>
          </TouchableOpacity>
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#E8EAED',
  },
  tasksWrapper: {
    paddingTop: 80,
    paddingHorizontal: 20,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: 'bold',
  },
  items: {
    marginTop: 30,
  },
  writeTaskWrapper: {
    position: 'absolute',
    bottom: 60,
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  createPartySection: {
    flexDirection: 'column',
    flex: 1,
    paddingHorizontal: 10,
  },
  input: {
    paddingVertical: 15,
    paddingHorizontal: 15,
    backgroundColor: '#FFF',
    borderRadius: 60,
    borderColor: '#C0C0C0',
    borderWidth: 1,
    width: '100%',
    marginBottom: 10,
  },
  addWrapper: {
    width: 60,
    height: 60,
    backgroundColor: '#FFF',
    borderRadius: 60,
    justifyContent: 'center',
    alignItems: 'center',
    borderColor: '#C0C0C0',
    borderWidth: 1,
    marginRight: 10,
  },
  addText: {},
  // 新增样式
  partyItem: {
    marginBottom: 15,
    padding: 15,
    borderWidth: 1,
    borderColor: '#eee',
    borderRadius: 8,
    backgroundColor: '#fff',
  },
  selectedParty: {
    borderColor: '#2196F3',
    backgroundColor: '#E3F2FD',
  },
  userListTitle: {
    fontSize: 16,
    fontWeight: '600',
    marginTop: 10,
    marginBottom: 5,
  },
  userItem: {
    fontSize: 14,
    paddingVertical: 2,
    paddingLeft: 10,
  },
  addUserSection: {
    position: 'absolute',
    bottom: 10,
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    paddingHorizontal: 10,
  },
  userInput: {
    flex: 1,
    marginBottom: 0,
  },
});

关键说明

  • 选中派对:点击任意派对即可选中,选中后会显示高亮样式,此时输入用户名并点击「添加用户」即可将用户加入该派对
  • 用户ID唯一性:通过取当前派对用户ID的最大值加1来生成新ID,避免重复
  • 输入校验:创建派对时必须填写名称,添加用户时必须选中派对且输入用户名,避免无效操作

内容的提问来源于stack exchange,提问作者User G Amsterdam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:40:47