简体   繁体   中英

How can I get data from a local file into my React app?

I have a txt file that I want to parse and have some data from that be used to populate part of a React app. I've been banging my head against the wall a bit because from what I've seen, I can't use fs in React (because it runs in a browser environment), nor can I use AJAX to look at local files.

I understand why, and I understand the security concerns around AJAX and local files. However, is there any way for me to get those bits of text into my app?

Code for the component in question is below as I said, I already know that using fs here isn't going to work).

import React from 'react';
import PropTypes from 'prop-types';
import fs from 'fs';

function StopList (props) {
var firstInstance = new RegExp(`^${props.subway}`);
var stops = [];
function stopNames() {
    fs.readFile('..utils/stops.txt', null, (err, data) => {
        if (err) {
            return console.log(err);
        } else {
            var stopData = data.split('\n');
        }
        stopData.map((line) => {
            if (firstInstance === line.charAt(0)) {
                var firstCommas = line.indexOf(',,');
                var secondCommas = line.indexOf(',,', firstCommas);
                stops.push(line.slice(firstCommas + 2, secondCommas));
            }
        });
    });
}
stopNames();
return (
    <select>
        {
            stops.map((stop) => {
                <option key={stop}>
                    {stop}
                </option>
            })
        }
    </select>
)
}
StopList.PropTypes = {
    stops: React.PropTypes.array.isRequired,
    subway: React.PropTypes.string.isRequired
};

export default StopList;

EDIT: The file in question is already online at http://web.mta.info/developers/data/nyct/subway/google_transit.zip . The problem is I wouldn't know how to get at it and read it online because it's inside a zip directory.

What are you using to bundle your application? If you're using Webpack, you can use the raw-loader and directly import the txt file into your app.

Raw loader: https://github.com/webpack-contrib/raw-loader

Then you can simply: import txt from 'file.txt';

Either way you need to pull the data from your local file system and include it in your bundle using some method.

You could use:

<input type=file></input> 

and have the user manually give the file to your app.

Since you mentioned in comments that you used create-react-app for your project, the best solution at the moment would be a babel plugin called Raw.Macro .

This plugin allows you to access content of your files without a need to create-react-app eject . Provides really elegant solution without any boilerplate code.

Note: There is a small drawback that you have to re-start your webpack dev server when the file changes, because the content of a file is being embedded during the build process.

    import raw from 'raw.macro';

    function foo(){
        const jsonContent = raw('../utils/stops.json');
        console.log(jsonContent);
    }

Have a look at PapaParse

http://papaparse.com/docs#local-files

It has the ability to read and parse local CSV files, which I think is what you are looking for.

There is also jsonfile, but that may use fs under the hood. https://github.com/jprichardson/node-jsonfile

I ran into a similar head-banging issue for loading a local csv. The first challenge is getting webpack to include the local file in the build. The best way to do that in Webpack 5 is with asset modules :

webpack.config.js

...
{
  test: /\.(csv)$/i,
  type: 'asset',
}

The second challenge is encapsulating the data into a variable. As Dan says, the best way is not AJAX, but using a named import.

import blob from './foo.csv';
console.log(blob)

---
data:text/csv;base64,U3RhdGUsQWJ...

blob is now a string. You need to extract the encoded value that represents your file contents and decode it from base64.

const encodedData = blob.split(",")[1] 
const data = atob(encodedData)
console.log(data)

---
header1,header2
val1,val2

Now data can be supplied to a csv parser (eg PapaParse).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM