【问题标题】:TypeError: Cannot read property 'userName' of undefined in reactTypeError:无法读取反应中未定义的属性“用户名”
【发布时间】:2021-01-14 16:46:18
【问题描述】:

出现“用户名未定义”之类的错误,不知道发生了什么错误,因为我已声明用户名仍然出现错误,请尝试解决我的错误

https://ibb.co/7jGyCD1

这是我出错的代码

import React from 'react';
import './Message.css';
import {Card,Typography,CardContent} from '@material-ui/core';


const Message = ({message,userName}) => {

    const isUser = userName === message.userName;

    return (
        <div className={`message ${isUser && 'message_user'}`}>
            <Card className={isUser ? 'message_userCard' : 'message_guestCard'}>
                {/* if the user is logged in then show the user card  otherwise show the styiling */}
                <CardContent>
                    <Typography 
                    color='white'
                    varient='h5'
                    component='h2'>
                    <h2>{message.userName} : {message.message}</h2>
                    </Typography>
                </CardContent>
            </Card>
        </div>
    )
}

export default Message;

App.js 这是我的 app.js 文件,我在其中编写了所有逻辑代码,并使用 firebase 将数据存储在数据库后端

import React, { useEffect, useState } from 'react';
import './App.css';
import { Button, Input } from '@material-ui/core';
import FormControl from '@material-ui/core/FormControl';
import Message from './Message';
import db from './Firebase';


const App = () => {

  const [input, setInput] = useState('');
  const [messages, setMessages] = useState([]);
  const [userName,setuserName] = useState('');

  // console.log(input);
  // console.log(messages);
  // console.log(userName);

  //every single time when database change or add value in dayabase then onSnapshot run
  useEffect(()=>{
    db.collection('messages').onSnapshot(snapshot=>{
      setMessages(snapshot.docs.map(doc=>{
        doc.data()
      }))
    })
  },[]);

  useEffect(()=>{
    setuserName(prompt('enter your name'))
  },[])

  //in above whenever my input value change inside useEffect code run

  const sendMessage = (e) => {
    e.preventDefault()
    setMessages([...messages, {userName: userName, text:input}])
    setInput('');
  }

  //usestate= variable in react its just a peace of code
  //useffetc = it is block of code that can executed based on a condition


  return (
    <div className="App">
      <form>
        <h1>Welcome Ashish</h1>
         <h2>Welcome {userName}</h2>
        <FormControl>
          <Input value={input} onChange={(e) => setInput(e.target.value)} />
          <Button disabled={!input} variant='contained' color='primary' type='submit' onClick={sendMessage}>send message</Button>
        </FormControl>
      </form>

      {
        messages.map(message => (
          <Message userName={userName} message={message}/>
        ))
      }
    </div>
  );
}

export default App;

【问题讨论】:

    标签: reactjs firebase react-hooks jsx


    【解决方案1】:

    您需要确保的第一件事是仅当消息数组存在时才需要对其进行映射。请考虑下面的代码。我添加了一项检查,仅在存在消息时才呈现消息组件。

    import React, { useEffect, useState } from 'react';
    import './App.css';
    import { Button, Input } from '@material-ui/core';
    import FormControl from '@material-ui/core/FormControl';
    import Message from './Message';
    import db from './Firebase';
    
    
    const App = () => {
    
      const [input, setInput] = useState('');
      const [messages, setMessages] = useState([]);
      const [userName,setuserName] = useState('');
    
      // console.log(input);
      // console.log(messages);
      // console.log(userName);
    
      //every single time when database change or add value in dayabase then onSnapshot run
      useEffect(()=>{
        db.collection('messages').onSnapshot(snapshot=>{
          setMessages(snapshot.docs.map(doc=>{
            doc.data()
          }))
        })
      },[]);
    
      useEffect(()=>{
        setuserName(prompt('enter your name'))
      },[])
    
      //in above whenever my input value change inside useEffect code run
    
      const sendMessage = (e) => {
        e.preventDefault()
        setMessages([...messages, {userName: userName, text:input}])
        setInput('');
      }
    
      //usestate= variable in react its just a peace of code
      //useffetc = it is block of code that can executed based on a condition
    
    
      return (
        <div className="App">
          <form>
            <h1>Welcome Ashish</h1>
             <h2>Welcome {userName}</h2>
            <FormControl>
              <Input value={input} onChange={(e) => setInput(e.target.value)} />
              <Button disabled={!input} variant='contained' color='primary' type='submit' onClick={sendMessage}>send message</Button>
            </FormControl>
          </form>
    
          { 
            messages && messages.length && messages.map(message => (
              <Message userName={userName} message={message}/>
            ))
          }
        </div>
      );
    }
    
    export default App;
    

    【讨论】:

    • messages.map(message =&gt; message ? (&lt;Message userName={userName} message={message} /&gt;) : null) 更好。
    【解决方案2】:
    useEffect(()=>{
      db.collection('messages').onSnapshot(snapshot=>{
        setMessages(snapshot.docs.map(doc=>{
          // ?  you miss out the `return` here
          return doc.data()
        }))
      })
    },[]);
    

    【讨论】:

      【解决方案3】:

      我觉得可能是这个原因

      可能在您创建用户名的使用状态时。 确保它像这样“setUserName”。我不知道它是对还是错。我总是这样写。根据您的 App.js 中的代码更改您的代码。

      【讨论】:

        猜你喜欢
        • 2019-07-27
        • 2016-05-08
        • 1970-01-01
        • 2022-09-27
        • 1970-01-01
        • 2020-09-07
        • 2021-06-22
        • 2021-07-10
        • 2017-01-01
        相关资源
        最近更新 更多