【问题标题】:How to fix this error with my code? Type error cannot read property of null?如何使用我的代码修复此错误?类型错误无法读取 null 的属性?
【发布时间】:2020-03-25 20:51:57
【问题描述】:

在我运行我的代码的那一刻,我得到一个 null 的“无法读取属性”年龄,它破坏了我的代码,我该如何进行检查以便它只在我登录时运行?我以为我是使用路由来做到这一点的,但显然不是

App.js 页面上的路由代码:在此页面上,firebase 检查身份验证,元素有条件地呈现给 DOM,同时 User_data 也从数据库中提取并存储到内部存储中,稍后调用它主页。

constructor(props) {
    super(props);
    this.state = {
      user: {},
    }
    this.authListener = this.authListener.bind(this);
  }

 //onload runs funtion to check for authenication from firebase
  componentDidMount() {
    this.authListener();
  }

//checks firebase for authentication
  authListener() {
    Authentication.auth().onAuthStateChanged((user) => {
      console.log(user);
      if (user) {
        this.setState({ user });
        localStorage.setItem('user', user.uid);
        this.pulldata_Health();
        this.pulldata_Meals();
        this.pulldata_Ingredients();
      } else {
        this.setState({ user: null })
        localStorage.removeItem('user');
      }
    });
  }

  //connects to database and stores data to local storage
  pulldata_Health() {
    database.collection('Health_data')
      .doc(localStorage.getItem('user'))
      .get()
      .then(doc => {
        const data = doc.data();
        localStorage.setItem('user_data', JSON.stringify(data));
        console.log(JSON.parse(localStorage.getItem('user_data')))
      }).catch(function (error) {
        console.error("Error reading health", error);
      });

  }

 render() {
    //reders different elements depding on authenticaion and if sidedrawer is open
    let backdrop;
    if (this.state.sideDrawerOpen) {
      backdrop = <Backdrop click={this.backdropClickHandler} />
    };

    return (
      <div className="App_margin">
        <Router>
          <div className='App'>
            {this.state.user ? (<Nav drawerClickHandler={this.drawerToggleClickHandler} />) : (<Login_bar />)}
            <SideDrawer sidedrawerClickHandler={this.sidedrawerToggleClickHandler} show={this.state.sideDrawerOpen} />
            {backdrop}

            {this.state.user ? (
              < Switch >
                <Route path='/setup_page' component={setup_page} exact />,
                <Route path='/settings_page' component={settings_page} exact />,
                <Route path='/' component={Main_page} />
              </Switch>
            ) : (<Login_page/>)}


          </div>
        </Router>
      </div>
    );
  }

导致问题的主页面组件的代码:当某些用户数据在停止问题后存储时,即使在注销时也是如此。所以我需要找到一种方法来停止在应用程序加载后立即调用此函数但我不确定如何做到这一点想知道我是否可以再次使用用户状态作为条件但我认为这会导致同样的问题?

const healthData = JSON.parse(localStorage.getItem('user_data'));
        console.log(healthData);
        return (
            <div className='main_Main'>
                <div className='meal_divs'>
                    <p className='food_heading'>Status:</p>
                    <p className='food_text'>Your age is: { healthData.age }</p>
                    <p className='food_text'>Your gender is: {healthData.gender}</p>
                    <p className='food_text'>Your goal is: {healthData.goal}</p>
                    <p className='food_text'>Your height is: {healthData.height}</p>
                    <p className='food_text'>your weight is: {healthData.weight}</p>
                </div>

任何想法帮助将不胜感激 idk 如何解决此问题

2020 年 3 月 25 日更新:

我最初只是在下面添加了前面提到的代码,它确实修复了我启动此线程的主要错误

return healthData == null ? "" : (
            <div className='main_Main'>...

这会在登录后停止渲染元素,除非用户一旦登录就很难休息。 然后,我使用 componentDidMount() 函数从本地存储中提取 user_data,该函数修复了登录后不呈现的 HTML 元素,但现在用户数据不显示,除非我在登录后硬重置(Ctrl+R)任何人都知道如何修复?这是当前代码。

  constructor(props) {
            super(props);
            this.state = {
                healthData: {}
            }
        }

        componentDidMount() {
            this.state.healthData = JSON.parse(localStorage.getItem('user_data'))
        }


        render() {
            //gets users data and renders it to <p> items
            const healthData = this.state.healthData;
            console.log(healthData);
            return healthData == null ? "" : (
                <div className='main_Main'>
                    <div className='meal_divs'>
                        <p className='food_heading'>Status:</p>
                        <p className='food_text'>Your age is: {this.state.healthData.age}</p>
                        <p className='food_text'>Your gender is: {healthData.gender}</p>
                        <p className='food_text'>Your goal is: {healthData.goal}</p>
                        <p className='food_text'>Your height is: {healthData.height}</p>
                        <p className='food_text'>your weight is: {healthData.weight}</p>
                    </div>

所以它的 {healthData} 现在在登录时没有呈现请帮助谢谢

2020 年 3 月 25 日 12:02 更新: 渲染 Html 元素的唯一原因是因为我将 healthData 的状态设置为 {},它不再为 null,但是当我在开始时将状态设置为 Null 或未定义时,{} 仍然为空,我遇到了同样的问题。

【问题讨论】:

  • 对不起,如果语法晚了,我很累,哈哈
  • 你可以使用 return healthData == null 吗? "" : (
    ********
  • @AnthonyMcGrath 嗨 anthony 感谢您的帮助,这可以正常工作并修复登录,但我似乎遇到的唯一问题是它似乎在登录到站点时并没有像加载时那样呈现user_data 仍然为空,我将尝试在主页上使用 componentDidMount() 来获取 user_data 并将报告回来
  • @lukeet 作为 Stackoverflow 的初学者,要获得良好的体验,请尝试提出非常精确和切中要害的问题。没有多个调试相关问题
  • 例如,这里的一个好问题是:您确实设置了状态“一些代码”,然后在状态“一些代码”中渲染值,然后更新状态“一些代码”,但状态不会更新。

标签: javascript html reactjs


【解决方案1】:

在react中按流

为什么不在构造函数中这样做呢?

 constructor(props) {
                super(props);
                this.state = {
                    healthData:JSON.parse(localStorage.getItem('user_data')) 
                }
  }
  componentDidMount() {
    //in case you are updating user_data somewhere
       this.setState({ 
        healthData:JSON.parse(localStorage.getItem('user_data'))});
      }
  render(){
                //gets users data and renders it to <p> items
                const healthData = this.state.healthData;
                console.log(healthData);
                return healthData == null ? "" : (
                    <div className='main_Main'>
                        <div className='meal_divs'>
                            <p className='food_heading'>Status:</p>
                            <p className='food_text'>Your age is: {healthData.age}</p>
                            <p className='food_text'>Your gender is: {healthData.gender}</p>
                            <p className='food_text'>Your goal is: {healthData.goal}</p>
                            <p className='food_text'>Your height is: {healthData.height}</p>
                            <p className='food_text'>your weight is: {healthData.weight}</p>
                        </div>
                       )
             }

【讨论】:

  • 谢谢,我会试试这个,但这不会使 const 健康数据变得多余吗?
  • 你可以直接使用“this.state.healthData”
  • 刚刚意识到构造函数中的设置不起作用而我没有使用它是因为登录页面被路由/在开始时没有找到用户这意味着构造函数在没有 user_data 返回 null 的情况下运行这就是为什么它在加载时未定义但我知道如何解决谢谢
  • 嘿,你有没有尝试在组件中使用 this.setState 并安装...你不应该直接写 this.state.something="something"
  • 是的,很有趣,只是补充说它并没有改变任何东西,但大胆地改进了我的代码
猜你喜欢
相关资源
最近更新 更多
热门标签