当我在this.state中填充数组时,为什么它返回未定义?

时间:2018-07-30 03:45:53

标签: javascript reactjs array.prototype.map

在我的应用中,我有一个home组件,该组件在用户登录后呈现。在此家庭组件的componentDidMount中,我获取与已登录用户关联的文档。提取调用有效,并且响应中填充了正确的数据。我获取这些数据并进行this.setState调用,将提取的数据设置为this.state。

在home组件渲染函数中,我插入JSX,它调用一个函数来映射this.state.docs并显示该数据。即使this.state中的数据可以成功地记录在Home组件的render函数中,但映射到数据的结果始终返回未定义。

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

这是我的家庭组成部分:

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;

1 个答案:

答案 0 :(得分:2)

您正在将Spam的状态设置为index,这是数组内部的数组。直接使用docs数组:

[resp.data.docs]