当我映射 this.state 中的填充数组时,为什么它 return 未定义?

When I map over a populated array in this.state, why does it return undefined?

在我的应用程序中,我有一个在用户登录后呈现的主页组件。在这个主组件的 componentDidMount 中,我获取了与登录用户关联的文档。 fetch 调用有效,响应中填充了正确的数据。我获取此数据并进行 this.setState 调用,将获取的数据设置为 this.state.

在主组件渲染函数中,我插入了 JSX,它调用一个函数来映射 this.state.docs 并显示该数据。即使 this.state 中的数据可以成功记录到 Home 组件的渲染函数中,但数据映射的结果始终 returns undefined.

如果我创建一个新文档,它确实会被插入并正确显示,但旧文档永远不会显示。

这是我的主页组件:

import React from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const axiosConfig = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json'
  }
};

class Home extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      docs: [],
      username: '',
      userid: '',
      newDocumentName: '',
      newDocumentPassword: '',
      loading: true
    };
    console.log('this.props in home constructor ', this.props);
  }

  newDoc() {
    console.log('this.state before new doc ', this.state);
    axios(localStorage.getItem('url') + '/newDoc', {
      method: 'post',
      data: {
        title: this.state.newDocumentName,
        password: this.state.newDocumentPassword
      },
      withCredentials: true
    }).then(resp => {
      console.log('the response to new doc ', resp);
      this.setState({
        docs: [...this.state.docs, resp.data.document],
        newDocumentName: '',
        newDocumentPassword: ''
      });
    });
  }

  renderDocumentList() {
    return this.state.docs.map((doc, i) => (
      <div key={i}>
        <Link to={`/editDocument/${doc._id}`}>{doc.title}</Link>
      </div>
    ));
  }

  logout() {
    axios
      .post('http://localhost:3000/logout')
      .then(resp => {
        this.props.history.replace('/');
      })
      .catch(error => console.log(error));
  }

  async componentDidMount() {
    try {
      let resp = await axios
        .get(
          localStorage.getItem('url') +
            '/getAllDocs/' +
            this.props.match.params.userid,
          axiosConfig
        )
        .then(resp => {
          console.log('awaited response in comp did mount of home ', resp);
          this.setState({
            docs: [resp.data.docs],
            username: resp.data.username,
            userid: resp.data.userid,
            loading: false
          });
        });
    } catch (e) {
      console.log(e);
    }
  }

  render() {
    if (this.state.loading) {
      return (
        <div>
          <h2>Loading...</h2>
        </div>
      );
    } else {
      return (
        <div className="page-container">
          <div className="document-header">
            <button className="logout-button" onClick={() => this.logout()}>
              Logout
            </button>
            <h3>Welcome, {this.state.username}.</h3>
          </div>
          <div className="create-or-share-document-div">
            <input
              type="text"
              placeholder="New document name"
              name="newDocumentName"
              value={this.state.newDocumentName || ''}
              onChange={event => {
                this.setState({ newDocumentName: event.target.value });
              }}
              style={{ width: '30%' }}
            />
            <input
              type="password"
              placeholder="new document password"
              name="newDocumentPassword"
              value={this.state.newDocumentPassword || ''}
              onChange={event => {
                this.setState({ newDocumentPassword: event.target.value });
              }}
              style={{ width: '30%' }}
            />
            <button
              style={{
                border: 'solid black 1px',
                padding: '5px',
                borderRadius: '10px',
                height: '3%',
                backgroundColor: 'lightgrey'
              }}
              onClick={() => this.newDoc()}
            >
              Create Document
            </button>
          </div>
          <div className="document-container">
            <div className="document-list">
              <p>My Documents:</p>
              <ul>{this.renderDocumentList()}</ul>
            </div>
          </div>
          <br />
          <div className="create-or-share-document-div">
            <input
              style={{ width: '30%' }}
              type="text"
              placeholder="paste a docID to collab on a doc"
              ref="sharedDoc"
            />
            <button
              style={{
                border: 'solid black 1px',
                padding: '5px',
                borderRadius: '10px',
                height: '3%',
                backgroundColor: 'lightgrey'
              }}
            >
              Add Shared Doc
            </button>
          </div>
        </div>
      );
    }
  }
}

export default Home;

您正在将状态中的 docs 设置为 [resp.data.docs],这是数组中的数组。直接使用resp.data.docs数组代替:

this.setState({
  docs: resp.data.docs,
  username: resp.data.username,
  userid: resp.data.userid,
  loading: false
});