【问题标题】:ReactJS: TypeError: Cannot read property 'name' of undefinedReactJS:TypeError:无法读取未定义的属性“名称”
【发布时间】:2018-08-26 07:54:04
【问题描述】:

使用 ReactJS、Redux 和 Firestore 创建新记录时出现错误。但是我不明白原因,因为我在 Redux 中正确获取了更新信息,但是在创建记录并返回查看所有记录后,我得到了错误:

TypeError:无法读取未定义的属性“名称”

如果我访问可视化记录一切都很好,问题是当我生成新记录并返回以可视化所有时。

我的 JSON 响应如下:

1: 
data: {email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar"}
uid: "2ts2DopIoXoiMVJ6lMKi"

当我返回获取所有记录并执行 console.log(this.props.clients) 时返回:

0:DocumentReference
firestore:
Firestore {_queue: AsyncQueue, INTERNAL: {…}, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, …}
id:(...)
parent:(...)
path:(...)
_firestoreClient:FirestoreClient {platform: BrowserPlatform, databaseInfo: DatabaseInfo, credentials: FirebaseCredentialsProvider, asyncQueue: AsyncQueue, clientId: "BGuRUAvN7ZQxmmNEZmbx", …}
_key:DocumentKey {path: ResourcePath}
__proto__:Object

这是我的代码:

操作:从 Firestore 获取数据

export const getFromFirestore= () => async dispatch => {
    let res = [];
    await db.collection('users').get().then((snapShot) => {
         snapShot.docs.map( doc => {
             res.push({ uid: doc.id, data: doc.data()});
         })
    }, error => {
        console.log(error)
    });

    dispatch({
        type: GET_CLIENTS,
        payload:res
    });
}

减速机:

    case GET_CLIENTS:
    return{
        ...state,
        clientsFirestore: action.payload
    };

客户端组件显示来自 Firestore 的数据:

class Clients extends Component {

     componentDidMount(){
      this.props.getFromFirestore();
    };

    deleteClient = (id) => {
      this.props.deleteFirestore(id);
    }


  render() {
    const { clients } = this.props;
    return (
      <React.Fragment>
        <h1 className="display-4 mb-2">
          <span className="text-danger">Clients</span>
        </h1>
        <table className="highlight centered">
          <thead>
            <tr>
                <th>Name</th>
                <th>Last Name</th>
                <th>Email</th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
          </thead>
          {clients && clients !== undefined ? clients.map((client, key) => (
              <Client
                key={key}
                id={client.uid}
                name={client.data.name}
                lastName={client.data.lastName}
                email={client.data.email }
                deleteClient={this.deleteClient}
              />  
          )): null }
        </table>
      </React.Fragment>
    );
  }
}

Clients.propTypes = {
  clients: PropTypes.array.isRequired,
}

const mapStateToProps = (state) => ({
  clients: state.clients.clientsFirestore
});

export default connect( mapStateToProps, { getFromFirestore, deleteFirestore } )(Clients);

谢谢!

【问题讨论】:

  • 根据您的示例,唯一的建议是在name={client.data.name} client.data 中未定义,因此您必须检查您是否正确访问name,或者甚至整个data 对象是不需要
  • @KarenGrigoryan 我认为问题在于,当我添加新的 Firestore 记录时,不同数组的第一个元素返回类似:0:DocumentReference firestore: Firestore {_queue: AsyncQueue, INTERNAL: {…}, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, …} id:(...) whrn my array of objects is like: 1: data: {email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar"} uid: "2ts2DopIoXoiMVJ6lMKi" 但我不知道如何获取数据

标签: javascript reactjs firebase google-cloud-firestore


【解决方案1】:

您还应该检查客户端和客户端是否未定义,然后才进行映射,如果您确实有名为 name 的属性

检查下面的代码

{clients && clients != undefined ? clients.map((client, key) => (
              {client && client != undefined && client.data && (<Client
                key={key}
                id={client.uid && client.uid }
                name={client.data.name && client.data.name}
                lastName={client.data.lastName && client.data.lastName}
                email={client.data.email && client.data.email }
                deleteClient={this.deleteClient}
              />)}  
          )): null }

PS:- 当您发布此类问题时,请尝试发布 json 数据以快速找到解决方案

【讨论】:

  • 谢谢。我尝试了您的解决方案,但问题仍然存在:/
  • okey 也会向您发布 json 数据,即 this.props.clients。在 this.props.clients 中的一个对象中可能不存在 name 属性
  • 是对象数组还是只有一个对象?
  • 谢谢。是一个对象数组,因为我得到了 firestore 中的所有信息。
【解决方案2】:

在 Map 函数中可能是数据属性未定义,因此数据对象上的名称属性会抛出 TypeError: Cannot read property 'name' of undefined 在传递给&lt;Client /&gt; 元素之前检查数据属性是否有可用的名称属性。

<Client
    key={key}
    id={client.uid}
    name={typeof client.data.name !== 'undefined' && client.data.name}
    lastName={client.data.lastName}
    email={client.data.email }
    deleteClient={this.deleteClient}
/>

【讨论】:

  • 是的。属性“名称”可用,但仅当我访问以查看记录而不添加任何新的时
  • 我认为有些记录没有名称属性。您可以检查所有记录是否具有名称属性?在循环迭代中,数据对象上的 name 属性未定义。
  • 我认为问题在于,当我添加新的 firestore 记录时,不同数组的第一个元素返回如下内容:0:DocumentReference firestore: Firestore {_queue: AsyncQueue, INTERNAL: {…}, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, …} id:(...) whrn 我的对象数组如下:1: data: {email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar"} uid: "2ts2DopIoXoiMVJ6lMKi"
【解决方案3】:

在返回之前,添加一个 if 查询来检查客户端是否被获取,那么只有 map 函数才能使用客户端的内部对象。添加if (client === null) return &lt;text&gt;loading&lt;/text&gt; 或其他内容以避免获取错误,该错误将为嵌套对象返回 undefined。 编辑:在mapStateToProps 中将客户定义为 clients : this.state.clients

【讨论】:

  • 谢谢。我添加了clients &amp;&amp; clients !== undefined ? clients.map((client, key)...,但问题仍然存在。 :(
  • reducer 的 index.js 在哪里?您是否通过combinereducers 将reducer 连接到应用程序状态?
【解决方案4】:

解决方案:

export const addToFirestore = (client) => async dispatch => {
    let res ={ 
    id:'',
    data:{
        name:'',
        lastName:'',
        email:''
    }};

    await db.collection("users").add({ 
        name: client.name,
        lastName: client.lastName,
        email: client.email,
     })
    .then(function(docRef) {
        res.id = docRef.id;
        res.data.name = client.name;
        res.data.lastName = client.lastName;
        res.data.email = client.email;
    })
    .catch(function(error) {
        console.error("Error adding document: ", error);
    });

    dispatch({
        type: ADD_CLIENT,
        payload:res
    });
};

创建一个对象,因为firestore的答案只给我们带来了ID:|

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多