javascript - 如何将从 useEffect 中获取的初始值放入文本字​​段中?

标签 javascript reactjs firebase google-cloud-firestore material-ui

我有这个编辑页面,其中名字、姓氏和地址的初始值应来自使用 useEffect 从 firebase firestore 检索的数据。

 useEffect(() => {
    const unsubscribe = firestore
      .collection("users")
      .doc(uid)
      .onSnapshot((snapshot) => {
        const arr = [];
        arr.push({
          ...snapshot.data(),
        });

        setUsers(arr);
      });

    return () => {
      unsubscribe();
    };
  }, []);

handleSubmit 将更新的信息保存在 firestore 中:

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      const userRef = firestore.collection("users").doc(uid);
      const ref = userRef.set(
        {
          firstName,
          middleName,
          lastName,
          address,
        },
        { merge: true }
      );
      console.log(" saved");
    } catch (err) {
      console.log(err);
    }
  };

完整代码如下:

const edit = () => {
  const uid = location.state;
  const [isLoading, setIsLoading] = useState(false);
  const [users, setUsers] = useState([]);
  const [firstName, setFirstName] = useState("");

  useEffect(() => {
    const unsubscribe = firestore
      .collection("users")
      .doc(uid)
      .onSnapshot((snapshot) => {
        const arr = [];
        arr.push({
          ...snapshot.data(),
        });

        setUsers(arr);
        setIsLoading(true);
      });

    return () => {
      unsubscribe();
    };
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(firstName);
  };

  return (
    <div>
        {isLoading ? (
          <>
            {users &&
              users.map((user) => (
                <li style={{ listStyle: "none" }}>
                  <CardHeader title="Update Profile" />
                  <form onSubmit={handleSubmit}>
                    <TextField
                      type="text"
                      value={user.firstName}
                      variant="outlined"
                      label="First Name"
                      fullWidth
                      onChange={(e) => setFirstName(e.target.value)}
                    />
                    <Button type="submit"> Submit</Button>
                  </form>
                </li>
              ))}
          </>
        ) : (
          <h1>Loading...</h1>
        )}
    </div>
  );
};

export default edit;

假设我想编辑用户“John Park”的地址。这些文本字段应具有 John 的名字和姓氏的初始值,因此即使地址字段是唯一更新的字段,保存在 Firestore 中时,名字和姓氏字段也不会是空字符串。我该怎么做?谢谢。

最佳答案

您似乎正在更新本地状态,但它没有初始化为空字符串之外的任何内容。

您的更新应该针对您获取的用户的本地副本,并且提交处理程序应该获取特定用户以在后端进行更新。

const [users, setUsers] = React.useState([]);

更改处理程序 - 柯里化(Currying)函数以获取索引并返回处理程序。它将前一个 users 状态映射到下一个状态,更新指定索引处的用户。

const changeHandler = index => e => {
  const { name, value } = e.target;
  setUsers(users => users.map((user, i) => i === index
    ? {
      ...user,
      [name]: value,
    }
    : user,
  ));
};

提交处理程序 - 柯里化(Currying)函数,用于获取特定用户对象的索引以发送到后端。

const handleSubmit = index => async (e) => {
  e.preventDefault();

  try {
    const userRef = firestore.collection("users").doc(uid);
    const ref = userRef.set(
      { ...users[index] }, // <-- user by index
      { merge: true }
    );
    console.log(" saved");
  } catch (err) {
    console.log(err);
  }
};

将当前映射索引传递给处理程序。将 name 属性添加到与输入的用户属性名称匹配的每个字段。

return (
  <div>
    {isLoading ? (
      <>
        {users &&
          users.map((user, index) => (
            <li style={{ listStyle: "none" }}>
              <CardHeader title="Update Profile" />
              <form onSubmit={handleSubmit(index)}> // <-- pass index
                <TextField
                  type="text"
                  value={user.firstName}
                  variant="outlined"
                  label="First Name"
                  name="firstName" // <-- add name attribute
                  fullWidth
                  onChange={changeHandler(index)} // <-- pass index to handler
                />
                ... other fields
                <Button type="submit">Submit</Button>
              </form>
            </li>
          ))}
      </>
    ) : (
      <h1>Loading...</h1>
    )}
  </div>
);

关于javascript - 如何将从 useEffect 中获取的初始值放入文本字​​段中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68870528/

相关文章:

android - 如何在 Kotlin Gradle dsl 中使用 Firebase BoM?

firebase - Firebase 限制您多长时间?

javascript - 如何修改 JQuery 自动完成以获取大于指定长度的字符?

javascript - Mysql:sequelize 查询返回空结果

javascript - RxJs:经过一段时间后才有新值

javascript - 如何从主要的 Angular 组件设置 html 和 body 的样式?

javascript - 在父组件中测试子组件的按钮

reactjs - 使用 React Error Boundaries 破坏了浏览器导航

javascript - 更改 Material-UI 日期选择器的标题颜色

firebase - 来自 Flutter 中 firebase_auth 插件的更多用户数据