1

I'm currently working on using React to upload a CSV file and convert the data to an array so I can access phone numbers. I've actually got it almost completely functional, with just one problem: I can't figure out how to store the array properly in a variable (dataDump) on the global level. It stores it inside another array.

Here's a picture of my console so you can see what I mean.

I'm able to access the contents of dataDump if I use dataDump[0] (as seen in the function for handleClick), but that won't work for a global variable. I need to be able to send the array's values to other components/files, so I don't think having to call it like that will work. Chances are I'm over-complicating this in my head and the answer is incredibly simple, but I've spent the past 2-3 weeks learning React, Twilio, Mongodb etc. from scratch so my brain's not cooperating.

I'll appreciate any help! Thanks! Code below. (Note this is a component that's imported to the App page.)

import React from "react";
import CSVReader from "react-csv-reader";

var dataDump = [];

console.log(dataDump);


const papaparseOptions = {
  header: true,
  dynamicTyping: true,
  skipEmptyLines: true,
  transformHeader: header => header.toLowerCase().replace(/\W/g, "_"),
  complete: function(results) {
    dataDump.push(results.data);
    console.log(dataDump);
    var rows = results.data;
    let numbers = rows.map(a => a.phone_number); //make the results ONLY the phone numbers
    // console.log(numbers);

    document.getElementById("data2").innerHTML=numbers; //display the phone numbers

       }
     };

class Import extends React.Component {
    constructor(props) {
      super(props);
      this.state = {data:[]};
      this.handleClick = this.handleClick.bind(this);
  }

    handleForce = data => {
        // console.log(data.length);
        console.log(data);
        this.setState({data: data});

    };


    handleClick = () => {
        console.log("success");
        console.log(this.state.data);
        console.log("Next is Numbies:");
        let numbies = dataDump[0].map(a => a.phone_number);
        console.log(numbies);
      document.getElementById("data").innerHTML=numbies;

    }

  render() {
    return (
    <div className="container">
    <CSVReader
      className="csv-input"
      label="Select CSV file to import"
      onFileLoaded={this.handleForce}
      parserOptions={papaparseOptions}

    />
    <div>

    </div>
    <button onClick={this.handleClick.bind(this)}>
        Test
      </button>
      <div id="data" />
      <div id="data2" />
      <div id="data3">
      </div>
    </div>


    );
  }
}

export default Import;
// export default DataController;
CanApple
  • 39
  • 1
  • 3
  • If you are looking for "application_level_state" (aka global state) I will strongly recommend ```redux for react``` :) – August Jelemson Feb 25 '20 at 17:43
  • Does this answer your question? [When should I add Redux to a React app?](https://stackoverflow.com/questions/36631761/when-should-i-add-redux-to-a-react-app) – Pizza eu Feb 25 '20 at 17:59

1 Answers1

0

Under the hood React-Redux is using context and hooks these days, so don't bother implementing a Redux stack until you've outgrown the simpler, React API, or at least you've fixed your issue. Folks joke that Redux is like shooting a fly with a bazooka. More info on React-Redux internals here and here's the documentation for React's Context.

Some psuedo-code to get you on the right path:

// context.js
import { createContext } from 'react';
export const Store = createContext();

// app.js
import React from 'react';
import { Store } from './context';
import Import from './import'; // I wouldn't change the casing on or reuse a reserved keyword personally, maybe calling this something like 'CsvImporter' would be an improvement 

function App() {
  const [dataDump, setDataDump] = React.useState([]);
  return (
    <Store.Provider value={{ dataDump, setDataDump }}>
      <Import dataDump={dataDump} setDataDump={setDataDump} />
    </Store.Provider>
   );
}

Now your import component has two new props, dataDump and setDataDump. You can call setDataDump just like any other call to setting state. Nice!

So you need the dataDump in a new component? That's easy peasy, lemon squeezy, and all without global variables or tossing module scoping to the side:

// foobar.js
import React from 'react';
import { Store } from './context';

export function Foobar() {
  // you probably want to do more than force render an array as a string, but this is just a proof of concept
  return (
    <Store.Consumer>
      {({ dataDump, setDataDump }) => (
        <p>
          `${dataDump}`
        </p>
      )}
    </Store.Consumer>
  );
}

Just make sure that Foobar or other components are rendered as children of the Provider in app.js and now you have a 'global' context for passing around dataDumps.

BEVR1337
  • 623
  • 4
  • 10