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

时间:2018-08-26 07:54:04

标签: javascript reactjs firebase google-cloud-firestore

使用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);

谢谢!

4 个答案:

答案 0 :(得分:0)

还应该检查客户端和客户端是否未定义,然后再进行映射,以及是否确实具有名为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数据以快速找到解决方法

答案 1 :(得分:0)

在Map函数中,数据属性可能未定义,因此数据对象抛出TypeError: Cannot read property 'name' of undefined时的名称属性 在传递给<Client />元素之前,检查数据属性具有name属性。

<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}
/>

答案 2 :(得分:0)

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

答案 3 :(得分:0)

解决方案:

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:|