首页 > 解决方案 > 使用 React history.push() 重定向不反映输入

问题描述

我正在用 Firebase 构建一个应用程序并做出反应。

在那个 APP 中,当用户编辑他们的信息并按下提交按钮时,它会通过 history.push() 将他们重定向到用户信息页面。

用户信息和页面重定向都运行良好,但是重定向页面后,没有反映被编辑的用户信息,页面显示的是之前版本的用户信息。

这是我的代码。

import React, { useRef, useState } from "react"
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link, useHistory, Redirect, Route } from "react-router-dom"
import { db } from "../firebase"
import Dashboard from "../components/Dashboard"

export default function UpdateProfile() {
  const usernameRef = useRef()
  const emailRef = useRef()
  const passwordRef = useRef()
  const passwordConfirmRef = useRef()
  const { updateUser, currentUser, updatePassword } = useAuth()
  const [error, setError] = useState("")
  const [loading, setLoading] = useState(false)
  const history = useHistory()

  function handleSubmit(e) {
    e.preventDefault()
    if (passwordRef.current.value !== passwordConfirmRef.current.value) {
      return setError("Passwords do not match")
    }

    if (passwordRef.current.value) {
      updatePassword(passwordRef.current.value)
    }

    const uid = currentUser.uid
    db.collection('users').doc(uid).get()
    .then(snapshot => {
      const data = snapshot.data() 
      try {
        setLoading(true)
        setError("")
        updateUser(usernameRef.current.value, emailRef.current.value, data)
        history.push('/dashboard')
      } catch {
        setError("Failed to update account")
      }
      setLoading(false)
    })
  }

  return (
    <>
      <Card>
        <Card.Body>
          <h2 className="text-center mb-4">Update Profile</h2>
          {error && <Alert variant="danger">{error}</Alert>}
          <Form onSubmit={handleSubmit}>
            <Form.Group id="username">
              <Form.Label>Name</Form.Label>
              <Form.Control
                type="text"
                ref={usernameRef}
                required
                defaultValue={currentUser.username}
              />
            </Form.Group>
            <Form.Group id="email">
              <Form.Label>Email</Form.Label>
              <Form.Control
                type="email"
                ref={emailRef}
                required
                defaultValue={currentUser.email}
              />
            </Form.Group>
            <Form.Group id="password">
              <Form.Label>Password</Form.Label>
              <Form.Control
                type="password"
                ref={passwordRef}
                placeholder="Leave blank to keep the same"
              />
            </Form.Group>
            <Form.Group id="password-confirm">
              <Form.Label>Password Confirmation</Form.Label>
              <Form.Control
                type="password"
                ref={passwordConfirmRef}
                placeholder="Leave blank to keep the same"
              />
            </Form.Group>
            <Button disabled={loading} className="w-100" type="submit">
              Update
            </Button>
          </Form>
        </Card.Body>
      </Card>
      <div className="w-100 text-center mt-2">
        <Link to="/">Cancel</Link>
      </div>
    </>
  )
}

我使用 AuthContext 将 Firebase 凭据传递给每个组件。这是 AuthContext 文件的一部分。

  function updateUser(username, email, data) {
    const uid = data.uid
    db.collection('users').doc(uid).set({
      email: email,
      username: username,
    }, {merge: true})
  }

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(async(user) => {
      if (user) {
        const uid = user.uid
        console.log(uid)
        await db.collection('users').doc(uid).get()
          .then(snapshot => {
            const data = snapshot.data()
            setCurrentUser(data)
            setLoading(false)
          })
      }
    })
    
    return unsubscribe
  }, [])

你知道如何反映我在编辑屏幕上输入的值吗?

标签: javascriptreactjsfirebasegoogle-cloud-firestorereact-router

解决方案


sinceupdateUser是一个异步函数,因此您应该在函数中使用async awaitor.then语法,updateUser以便history.push在更新用户数据后调用

function updateUser(username, email, data) {
    const uid = data.uid
    return db.collection('users').doc(uid).set({
        email: email,
        username: username,
      }, {merge: true})
  }
     updateUser(usernameRef.current.value, emailRef.current.value, data)
       .then(() => {
           history.push('/dashboard');
       }

推荐阅读