динамический файл внутри папок не читается с помощью React и preval.macro - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь создать приложение, которое будет отображать список элементов, прочитанных из папки внутри моего приложения create-реагировать, и оно будет читать и показывать файл внутри папки.

import preval from 'preval.macro';
import '../index.css'

const components = preval
    ` const fs = require('fs');
  const files = fs.readdirSync('src/atoms');
  module.exports = files;
`

const AtomList = () => {

    const [newFileName, setNewFileName] = useState('avatar');


    const fileUnderComponent = preval
        `   const fs = require('fs')
            const path = require('path');
            const file = fs.readFileSync('src/atoms/${newFileName}/${newFileName}.js');
            module.exports = file.toString();
        `;

    const setNewComponent = (componentName) => {
        setNewFileName(componentName)
    }

    const eachAtom = (component) => {
        return (
            <ul><li className="list-item-group" onClick={() => setNewComponent(component)}>{component}</li></ul>
        )
    }

    return (
        <div>
            <div className="list-group inlineBlock atomList width20">
                <div>List of Reusable Components</div>
                {components.map((component, i) => {
                    return eachAtom(component)
                })}
            </div>
            <div className="list-group inlineBlock atomDescription width80">
                {typeof fileUnderComponent === 'string' ? fileUnderComponent : null}
            </div>

        </div>
    )
}

export default AtomList

ВПриведенный выше компонент, если я жестко закодировал newFileName как 'avatar', содержимое файла отображается, но когда я переключаю компоненты при нажатии на них, newFileName изменяется, но fileUnderComponent ничего не отображает.

Я думаю, вероятно, из-за операции readFileSyncчто занимает некоторое время. Я попытался поместить его в setTimeout, но не повезло.

Где я могу пойти не так?

1 Ответ

0 голосов
/ 22 октября 2019

Preval оценивает код во время сборки, поэтому запускать его при обновлении вашего состояния будет невозможно. Следующий код для извлечения содержимого файлов для предварительного просмотра работает нормально.

const contentOfComponents = preval`
const fs = require("fs");
const files = fs.readdirSync("src/atoms");
const content = files.map(filename => {
  const fs = require("fs");
  const url = 'src/atoms/'+filename+'/'+filename+'.js';
  return fs.readFileSync(url).toString();
})
module.exports = content`;

Вы можете использовать этот contentOfComponents, который представляет собой массив содержимого файлов, сопоставляя их с вашимcomponents массив и затем отображение соответствующего содержимого при щелчке имени файла.

Код из вопроса после внесения изменений, как указано выше

import React, { useState } from "react";
import preval from "preval.macro";
import shortid from "shortid";

const components = preval`
const fs = require("fs");
const files = fs.readdirSync("src/atoms");
module.exports = files`;

const contentOfComponents = preval`
const fs = require("fs");
const files = fs.readdirSync("src/atoms");
const content = files.map(filename => {
  const fs = require("fs");
  const url = 'src/atoms/'+filename+'/'+filename+'.js';
  return fs.readFileSync(url).toString();
})
module.exports = content`;

const AtomList = () => {
  const [fileUnderComponent, setFileUnderComponent] = useState(null);

  const setNewComponent = componentName => {
    const _index = components.indexOf(componentName);
    setFileUnderComponent(contentOfComponents[_index]);
  };

  const eachAtom = component => {
    return (
      <li
        key={shortid.generate()}
        className="list-item-group"
        onClick={() => setNewComponent(component)}
      >
        {component}
      </li>
    );
  };

  return (
    <div>
      <div className="list-group inlineBlock atomList width20">
        <div>List of Reusable Components</div>
        <ul>
          {components.map(component => {
            return eachAtom(component);
          })}
        </ul>
      </div>
      <div className="list-group inlineBlock atomDescription width80">
        {typeof fileUnderComponent === "string" ? fileUnderComponent : null}
      </div>
    </div>
  );
};

export default AtomList;

Также вашeachAtom функция не должна возвращать <ul>.

Сброшено! Это было первое впечатление

Это может быть синтаксической ошибкой. В вашей строке const file = fs.readFileSync('src/atoms/${newFileName}/${newFileName}.js'); вы уверены, что используете обратные тики , а не одинарные кавычки?

Это может решить эту проблему:

const file = fs.readFileSync(`src/atoms/${newFileName}/${newFileName}.js`);

Клавиша обратной галочки обычно находится в верхнем левом углу чуть ниже клавиши Esc и слева от клавиши с цифрой 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...