【问题标题】:React/Next - Proper way to generate state with dynamic dataReact/Next - 使用动态数据生成状态的正确方法
【发布时间】:2017-05-21 23:50:03
【问题描述】:

我正在尝试从文件列表中提取元数据并将它们显示在 div 中。元数据包含在文本文件中,并使用 front-matter 模块收集。

仍在学习 React,不确定创建状态的正确方法是什么。 任何帮助,将不胜感激。

import React from 'react'
import frontMatter from 'front-matter'
import fs from 'fs'

import { getFileList } from '../util/utils'

export default class TheFileList extends React.Component {
  constructor(props) {
    super(props);
    this.state = getFileList('./static/filecontainer/').then((files) => {
      const linkParams = files.nameList.map((fileName, i) => {
        const content = fs.readFileSync(files.pathList[i], 'utf-8')
        const meta = frontMatter(content)
        return {
          name: fileName,
          title: meta.attributes.title,
          date: meta.attributes.date,
          description: meta.attributes.description,
        }
      })
      return {
        linkParams: linkParams
      }
    })
  }

  render () {
    return (
      <div id="fileDumpContainer">
          {
            this.state.linkParams.map((el, i) => {
              return (
                <div className="itemBlock">
                  <div id="nameBlock"><div id='tFileTitle'>{el.title}</div><div id='tFileDate'>{el.date}</div></div>
                  <div id="descriptBlock"><p className='tFileInfo'>{el.description}</p></div>
                </div>
              )
            })
          }
      </div>
    )
  }
  }

实用功能:

import yaml from 'js-yaml'

export async function getFileList (dirname) {
  return new Promise((resolve, reject) => {
    fs.readdir (dirname, (error, files) => {
      if (error) {
        reject(error);
      } else {
        files.reverse()
        resolve({
          pathList: files.map( el => dirname + el ),
          nameList: files.map( el => el.slice(0, -3) )
        })
      }
    })
  })
}

这是我得到的错误:

Cannot read property 'map' of undefined

TypeError: Cannot read property 'map' of undefined
    at TheFileList.render (C:\reactApp\.next\dist\components\TheFileList.js:84:31)
    at C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:796:21
    at measureLifeCyclePerf (C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:75:12)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:795:25)
    at ReactCompositeComponentWrapper._renderValidatedComponent (C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:822:32)
    at ReactCompositeComponentWrapper.performInitialMount (C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:362:30)
    at ReactCompositeComponentWrapper.mountComponent (C:\reactApp\node_modules\react-dom\lib\ReactCompositeComponent.js:258:21)
    at Object.mountComponent (C:\reactApp\node_modules\react-dom\lib\ReactReconciler.js:46:35)
    at ReactDOMComponent.mountChildren (C:\reactApp\node_modules\react-dom\lib\ReactMultiChild.js:238:44)
    at ReactDOMComponent._createContentMarkup (C:\reactApp\node_modules\react-dom\lib\ReactDOMComponent.js:653:32)

【问题讨论】:

  • 该错误通常意味着您正在尝试使用无效的内容(例如,拼写错误的“divv”)创建 JSX,并且实际上与状态无关。我很好奇 el.title/date/description 是否都是字符串 - el.date 是一个对象吗?
  • el.date 是一个字符串“DD-MM-YYYY”
  • 我认为我解决了这个问题,但现在它找不到状态对象。
  • 不,它在 state 上找不到 linkParams。尝试给它一个默认值。
  • 认为问题是 Promise 对象在尝试渲染时仍处于挂起状态,这意味着它尚未检索文件列表,有没有办法让它等到 Promise 对象完成在尝试渲染之前?

标签: javascript reactjs next.js


【解决方案1】:

尝试在您的渲染函数中添加检查以查看是否存在 linkParams。通常适用于应用程序级状态(redux)

 render () {
  if(!linkParams){
    return <div>Loading</div>
  } else {
    return (
      <div id="fileDumpContainer">
          {
            this.state.linkParams.map((el, i) => {
              return (
                <div className="itemBlock">
                  <div id="nameBlock"><div id='tFileTitle'>{el.title}</div><div id='tFileDate'>{el.date}</div></div>
                  <div id="descriptBlock"><p className='tFileInfo'>{el.description}</p></div>
                </div>
              )
            })  }
  }

【讨论】:

  • 我试过了,它会显示“正在加载”,但之后不会更新。
  • 是的,您的组件应该在状态更新后重新渲染。我认为问题在于 React 没有内置的 Promise 中间件。由于您只使用 React,请查看 react-promise 包
猜你喜欢
  • 2011-12-02
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2019-09-16
相关资源
最近更新 更多