【问题标题】:React: form is clean when I refresh the pageReact:刷新页面时表单很干净
【发布时间】:2020-06-25 05:22:13
【问题描述】:

我是使用 React 的新手。我有一个名为 UpserProfile 的组件,它从 Firebase 获取数据并将这些数据放入一个表单中。目标是用户能够编辑他的数据/个人资料。

问题是:数据是在我加载页面时加载的。但是,如果我刷新页面,表单字段将变为空/干净。我做错了什么?有人可以帮我增加代码吗?

    class UserProfile extends React.Component{
    
        constructor(props){
            super(props);
            this.state = {
                authUser: null,
                userProfile: new UserProfileModel() // A model with all available properties seted with default values
            }
        }
    
    /**
     * Use auth listner to see if it had an user authenticated
     */
    componentDidMount() {
        this.props.firebase.auth.onAuthStateChanged((authUser) => {
            this.props.firebase.getUserData(authUser.uid).then((response)=>{     
                this.setState({ userProfile: {
                    id: response.id,
                    displayName: response.displayName || "", 
                    name: response.name || "", 
                    email: response.email || "",
                }});
            });
        });
    }
    
    handleInputChange = (event) => {
        let value = event.target.value;
        // If it's the termsAndPrivacy checkbox 
        this.setState({ [event.target.name]: value});
    }
    
    
    onSubmit = (event) => {
        // Prevent to submit the form
        event.preventDefault();
    
        this.props.firebase.user(this.userProfile.id).set(this.userProfile)
          .then(authUser => {
              console.log("Changed user:", authUser);
          })
          .catch(error => {
            console.log("Error: ", error);
            this.setState({ error });
        });
    }
    
    
    render(){
        return(
            <div>
                <BreadCrumb pageTitle="Edit Profile"/>
                <section className="container main-content">
                    <div className="row">
                        <div className="col-md-12">
                            <div className="page-content">
                                <div className="boxedtitle page-title"><h2>Edit Profile</h2></div>
                                <div className="form-style form-style-4">
                                    <form onSubmit={this.onSubmit}>
                                        <div className="form-inputs clearfix">
                                            <p>
                                                <label>Display Name*</label>
                                                <input name="displayName" type="text" onChange={this.handleInputChange} value={this.state.userProfile.displayName}/>
                                            </p>    
                                            <p>
                                                <label>Full name</label>
                                                <input name="name" type="text" onChange={this.handleInputChange} value={this.state.userProfile.name}/>
                                            </p>
                                            <p>
                                                <label className="required">E-Mail<span>*</span></label>
                                                <input name="email" type="email" onChange={this.handleInputChange} value={this.state.userProfile.email}/>
                                            </p>...

有人可以帮帮我吗?

更新: 这是我的 Firebase 课程:

import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import { UserProfileModel } from '../Models/UserProfileModel';

 const firebaseConfig = {
    apiKey: "AI------------------",
    authDomain: "mysite.firebaseapp.com",
    databaseURL: "https://mysite.firebaseio.com",
    projectId: "myprojectid",
    storageBucket: "mysite.appspot.com",
    messagingSenderId: "---------1",
    appId: "1--------------"
  };

  export default class Firebase {
    constructor() {
      app.initializeApp(firebaseConfig);
      this.auth = app.auth();
      this.db = app.database();
    }

async getUserData(uid){
      var userData = new UserProfileModel();
      this.user(uid).on('value', (snapshot) => {
          snapshot.forEach((childSnapshot) => {
              var keyName = childSnapshot.key;
              var childData = childSnapshot.val();
              userData[keyName] = childData;
          });
      });
      return userData;
    }

    // *** USER APO ***

    user = uid => this.db.ref(`users/${uid}`);
    users = () => this.db.ref('users');

【问题讨论】:

  • 嗨@william 这是反应组件的预期行为。当您刷新应用程序时,我将卸载并清除状态。
  • @rashijain,如何预防?也不应该再次刷新数据?
  • 不,如果我们想要在不进行提交调用的情况下刷新页面后仍要持久化数据,我们需要持续保存数据。我们还需要在 componentDidMount 中进行 API 调用,以从服务器获取数据并填写相应的字段。(此数据 API 调用已经存在)

标签: javascript reactjs


【解决方案1】:

您需要使用 Rebase 与您的 Firebase 数据库同步,例如:

Firebase.js:

import Rebase from 're-base';
import firebase from 'firebase';

const firebaseApp = firebase.initializeApp({ apiKey, authDomain, databaseURL, });
const base = Rebase.createClass(firebaseApp.database());

export { firebaseApp };

export default base;

App.js:

import base from '../Firebase';


componentDidMount() {
  ...

  this.ref = base.syncState(newState, {
    context: this,
    state: state
  });

}

【讨论】:

  • 感谢您的回答。我不明白把这个变基等放在哪里。现在,我使用了一个名为 Firebase.js 的单独类,其中我有 Firebase 设置(apiKey 域等)以及我与 Firebase 的连接。我必须在哪里放置这个组件 didMount()?
  • 通常,firebase 和 rebase 将位于一个单独的文件中(在您的情况下为 Firebase.js),componentDidMount() 将位于您的 App.js 文件中。我会更新答案以澄清。
【解决方案2】:

确保刷新页面后,firebase 调用会再次发生。这会将新数据设置为状态变量,并且数据将被预填充。

【讨论】:

  • 谢谢。但是,如何确定呢?当我再次刷新和 componentDidMount 时,它不应该发生吗?关于我调用firebase API的方式,通过道具传递它?
猜你喜欢
  • 1970-01-01
  • 2019-01-22
  • 2021-08-04
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
相关资源
最近更新 更多