Papa.parse componentDidMount shouldComponentUpdate 混乱
Papa.parse componentDidMount shouldComponentUpdate confusion
编辑:我认为这是 codesandbox 的 CORS 问题,但我还没有弄清楚如何使用静态 ip 甚至 localhost 进行托管。当我确认这是 papaparse 和 codesandbox 云之间的 CORS 问题时,我会更新 ide。我针对与 Domino 在同一个 papaparse 应用程序
上解决的问题不同的问题启动了 new question
Whosebug 上的这个问题是我与 Papa.parse 对话的延伸。
找到一个模式 here,类似地,我使用 this.function 传递每个对象,因为它是用 "City" 参数解析的,并尝试呈现 "WeatherCitySkyMap"每个城市的组成部分。如果我硬编码 let cities = [{ city: "New York" }, { city: "Baltimore" }];,渲染后的代码已经过测试,可以为 cities 数组中的每个城市渲染这样的组件;但是对于从北美 csv 城市列表的保管箱 link 解析的每个城市,我希望按 Papa.parse 步骤填充城市。
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 使用 UNSAFE_componentWillMount()),而不是我尝试在 Papa.parse 周围使用 componentDidMount(),但需要 Papa.parse results.data 在它们像 componentWillMount() 那样渲染之前发生(或者我应该在某个地方使用 shouldComponentUpdate & forceUpdate() 吗?)。我读到的最佳做法是用构造函数和 super 替换 componentWillMount,所以我应该把 Papa.Parse 放在构造函数中吗?我试过了,但迷路了。感谢您提前阅读和帮助。
Domino987 回答后的更新(到目前为止):
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;
所以对于组件的工作原理存在一些误解:
- 道具未传递给渲染:您可以使用
this.props
. 访问它们
- 开始时本地状态为 null:在您的构造函数中写入
this.state = {cities: []}
,如果您尝试在渲染中访问城市,这将防止破坏您的代码。
- 要在渲染和更新数据中访问城市,请使用
this.state.cities
。这样您就可以访问当前的城市。
- 要更新状态中的数组,请这样写:
this.setState(prevState => { cities: [...prevState.cities, results.data.City] });
。这将更新不可变的状态并保留以前的城市。
componentDidMount 是实现服务器调用、副作用或 Papa.parse 的正确方法。它会首先渲染没有数据的组件,但一旦数据出现,它就会更新它。该组件不会中断,因为对于第 2 点,状态不会为 null 并且渲染仍然有效。
我希望这些评论能帮助您使代码正常工作。
// 编辑
既然你问如何实现 updateData 和渲染,这里是一些代码:
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);
}
编码愉快。
编辑:我认为这是 codesandbox 的 CORS 问题,但我还没有弄清楚如何使用静态 ip 甚至 localhost 进行托管。当我确认这是 papaparse 和 codesandbox 云之间的 CORS 问题时,我会更新 ide。我针对与 Domino 在同一个 papaparse 应用程序
上解决的问题不同的问题启动了 new questionWhosebug 上的这个问题是我与 Papa.parse 对话的延伸。
找到一个模式 here,类似地,我使用 this.function 传递每个对象,因为它是用 "City" 参数解析的,并尝试呈现 "WeatherCitySkyMap"每个城市的组成部分。如果我硬编码 let cities = [{ city: "New York" }, { city: "Baltimore" }];,渲染后的代码已经过测试,可以为 cities 数组中的每个城市渲染这样的组件;但是对于从北美 csv 城市列表的保管箱 link 解析的每个城市,我希望按 Papa.parse 步骤填充城市。
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 使用 UNSAFE_componentWillMount()),而不是我尝试在 Papa.parse 周围使用 componentDidMount(),但需要 Papa.parse results.data 在它们像 componentWillMount() 那样渲染之前发生(或者我应该在某个地方使用 shouldComponentUpdate & forceUpdate() 吗?)。我读到的最佳做法是用构造函数和 super 替换 componentWillMount,所以我应该把 Papa.Parse 放在构造函数中吗?我试过了,但迷路了。感谢您提前阅读和帮助。
Domino987 回答后的更新(到目前为止):
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;
所以对于组件的工作原理存在一些误解:
- 道具未传递给渲染:您可以使用
this.props
. 访问它们
- 开始时本地状态为 null:在您的构造函数中写入
this.state = {cities: []}
,如果您尝试在渲染中访问城市,这将防止破坏您的代码。 - 要在渲染和更新数据中访问城市,请使用
this.state.cities
。这样您就可以访问当前的城市。 - 要更新状态中的数组,请这样写:
this.setState(prevState => { cities: [...prevState.cities, results.data.City] });
。这将更新不可变的状态并保留以前的城市。
componentDidMount 是实现服务器调用、副作用或 Papa.parse 的正确方法。它会首先渲染没有数据的组件,但一旦数据出现,它就会更新它。该组件不会中断,因为对于第 2 点,状态不会为 null 并且渲染仍然有效。
我希望这些评论能帮助您使代码正常工作。
// 编辑 既然你问如何实现 updateData 和渲染,这里是一些代码:
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);
}
编码愉快。