Papa.parse componentDidMount shouldComponentUpdate confusion

房东的猫 提交于 2019-12-11 15:41:16

问题


Edit: I think this is a CORS issue with codesandbox, but I haven't figured out how to host with static ip or even localhost yet. I'll update when I can confirm it is a CORS issue between papaparse and codesandbox cloud ide. I started a new question for a different problem than Domino solved here on the same papaparse application

This question here on StackOverflow is an extension of my conversation with Papa.parse.

A pattern is found here, similarly I use a this.function to pass down every object as it is parsed with "City" parameter & try to render a "WeatherCitySkyMap" component for each City. The code after render has been tested to render such a component for each City in the cities array if I hard code let cities = [{ city: "New York" }, { city: "Baltimore" }];, but I want cities to be populated by Papa.parse step for each City parsed from my dropboxlink of a csv list of cities in NorthAmerica.

class CitiesMap extends React.Component {
  constructor(props) {
    super(props);
    this.updateData = this.updateData.bind(this);
  }
  componentDidMount() {
    Papa.parse(
      "https://cors-anywhere.herokuapp.com/https://www.dropbox.com/s/5vcoo9r60hgczd1/worldcitiespop_northamerica_nolonglat.csv?dl=1",
      {
        download: true,
        header: true,
        worker: true,
        skipEmptyLines: true,
        step: this.updateData,
        complete: function() {
          console.log("all done");
        }
      }
    );
  }
  updateData(results) {
    cities.push(results.data, ["City"]);
    this.setState({ cities });
  }
  render(props) { 
    let filteredCities = cities.filter(cities => {
      return (
        cities.City.toUpperCase().indexOf(this.props.search.toUpperCase()) !==
        -1
      );
    });
    return (
      <div>
        <div className="Cities">
          {filteredCities.map(City => {
            return (
              <div>
                <WeatherCitySkyMap
                  description={this.description}
                  humidity={this.humidity}
                />
                {JSON.stringify([City])
                  .replace(/[^\w\s]/g, "")
                  .replace(/(city)/g, "")}
              </div>
            );
          })}
        </div>
      </div>
    );
  }
}

export default CitiesMap;

"This pattern is found here" link uses UNSAFE_componentWillMount()), instead I try to use componentDidMount() around Papa.parse, but need the Papa.parse results.data to happen before they render like componentWillMount() would have done (or should I use shouldComponentUpdate & forceUpdate() somewhere?). I read best practices is to replace componentWillMount with constructor and super, so should I put Papa.Parse in the constructor? I tried that and got lost. Thanks for reading & your help in advance.

UPDATE after Domino987 answer (so far):

import React from "react";
import WeatherCitySkyMap from "./WeatherCitySkyMap";
import Papa from "papaparse";

import ".././Explore/Cities.css";

class CitiesMap extends React.Component {
  constructor(props) {
    super(props);
    this.updateData = this.updateData.bind(this);
    this.state = { cities: [] };
  }
  componentDidMount() {
    Papa.parse( "https://dl.dropboxusercontent.com/s/k81s5enbamijuke/worldcitiespop_northamerica_nolonglat_few.csv?dl=0",
      {
        download: true,
        header: true,
        worker: true,
        skipEmptyLines: true,
        step: this.updateData,
        complete: function() {
          console.log("all done");
        }
      }
    );
  }
  updateData(results) {
    this.setState(prevState => ({
      cities: [...prevState.cities, results.data.City]
    }));
  }
  render(props) {
    let filteredCities = this.state.cities.filter(cities => {
      return (
        cities.toUpperCase().indexOf(this.props.search.toUpperCase()) !==
        -1
      );
    });
    return (
      <div>
        <div className="Cities">
          {filteredCities.map(City => {
            return (
              <div>
                <WeatherCitySkyMap
                  description={this.description}
                  humidity={this.humidity}
                />
                {JSON.stringify([City])
                  .replace(/[^\w\s]/g, "")
                  .replace(/(city)/g, "")}
              </div>
            );
          })}
        </div>
      </div>
    );
  }
}

export default CitiesMap;

回答1:


So there are a few misconceptions of how the component works:

  1. Props are not passed to render: You can access them with this.props.
  2. Local state is null at beginning: in your constructor write this.state = {cities: []}, This will prevent breaking your code if you try to access cities within render.
  3. To access cities in your render and updateData use this.state.cities. This will let you access the current cities.
  4. To update an array within the state write it like this: this.setState(prevState => { cities: [...prevState.cities, results.data.City] });. This will update the state immutable and will keep the previous cities.

componentDidMount is the correct way to implement a server call, side effect or Papa.parse. It will render the component without data first, but as soon as data is present, it will update it. The component will not break, because with point 2 the state will not be null and the render will still work.

I hope these remarks will help you get your code working.

// Edit Since you ask how to implement updateData and render, here is some code:

updateData(results) {
  // This will not work because cities is not defined here (us this.state.cities) and you mutate the data with push
  // cities.push(results.data.city); 
  // I am not sure why you add "City" but that is in your code
  this.setState(prevState => { cities: [...prevState.cities, results.data.City]});
}
render(props) {
  // Filter will check each city in the cities array, so you have to write it like this:
  const filteredCities = this.state.cities.filter(city => city.indexOf(this.props.search.toUpperCase()) !== -1);
}

Happy coding.



来源:https://stackoverflow.com/questions/57563114/papa-parse-componentdidmount-shouldcomponentupdate-confusion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!