将this.setState与来自不可变性助手的更新一起使用不会重新渲染React Component



我正在React项目中使用Google Maps API进行简单的地图实现。 当用户根据状态对象中 infoWindowStatus 的状态单击标记时,我向用户显示一个信息窗口。 如果信息窗口状态为 true,则会显示信息窗口。

如果我直接改变状态并使用强制更新,则信息窗口会正确显示。 当我使用 setState 时,信息窗口不显示。(但是,我可以看到,当我控制台时,infoWindowStatus 确实从 false 变为 true.log this.state.locations[myKey].infoWindowStatus。

我遇到的问题是: 将this.setState与来自不可变性助手的更新一起使用不会重新渲染React Component。

import update from 'immutability-helper';
state = {
locations : [
{
position: {lat: 41.3029876, lng: -72.9191306},
title: "Pepe's Pizza",
mappy: '',
infoWindowStatus: false,
key : 0,
infoWindow :
{
content : "Loading...",
contentUrl : ""
}
}
]
}
// THIS DODGEY CODE WORKS
this.state.locations[myKey].infoWindowStatus = true;
this.forceUpdate()
//THIS CODE DOES NOT WORK
this.setState(
{ locations: update(this.state.locations, { [myKey] : {infoWindowStatus: 
{$set:true}}})
}
);

请求的整个组件是:

import React, { Component } from 'react';
import './css/App.css';
import './css/Custom.css';
import NeighborhoodMap from './neighborhoodMap';
import 'typeface-roboto';
import escapeRegEx from 'escape-string-regexp';
import update from 'immutability-helper';
class App extends Component {
state = {
locations : [
{
position: {lat: 41.3029876, lng: -72.9191306},
title: "Pepe's Pizza",
mappy: '',
infoWindowStatus: false,
key : 0,
infoWindow :
{
content : "Loading...",
contentUrl : ""
}
}
]
}

// TODO: separate data into external data file.
componentDidMount(){

this.setState({
filteredLocationsOnly : this.state.locations
})
}
// Launches Info Window on Google Map
showInfoWindowNow(locationSelected){
let myKey;
this.state.locations.filter( (location) =>{
if (locationSelected.name === location.title || locationSelected.title === location.title){
myKey = location.key;
return location
}
} );
this.updateInfoWindowContentAgain(myKey);

// // THIS CODE DOES NOT WORK AT ALL
// this.setState({ locations[myKey].infoWindowStatus : true })

// // THIS CODE DOESN'T SHOW THE INFO WINDOW
// console.log("Status: ", this.state.locations[myKey].infoWindowStatus);
// const tempLocations = [...this.state.locations];
// tempLocations[myKey] = { ...tempLocations[myKey], infoWindowStatus: true };
//
//  this.setState(
//        {
//          locations: tempLocations
//        }
//  );
// console.log("Status Now: ", this.state.locations[myKey].infoWindowStatus);

// THIS DODGEY CODE WORKS
// https://stackoverflow.com/questions/51250518
this.state.locations[myKey].infoWindowStatus = true;
this.forceUpdate()

} //showInfoWindowNow

// Close Info Window on Google Map
closeInfoWindowNow(locationSelected){
this.forceUpdate()
}
// Update Content for Info Window
updateInfoWindowContentAgain(myKey){
return this.getInfoWindowContent(this.state.locations[myKey].title, myKey);
}
// Update Content for Info Window sub-function
getInfoWindowContent(searchTerm, myKey){
var nytAuthKey = "3d6801dab968446787ea71d5042ad8f7";
var myNewYorkTimesUrl = `https://api.nytimes.com/svc/search/v2/articlesearch.json?&api-key=${nytAuthKey}&q=${searchTerm}`
var contentForLocation;
var contentUrl;
let content = fetch(myNewYorkTimesUrl)
.then(response => response.json() )
.then(data => {
return addArticles(data);
}
)
.catch(error => requestError(error, 'articles'));
// add text from fetch request
function addArticles(data){
if (data.response && data.response.docs && data.response.docs.length > 1){
const articles = data.response.docs;
// var content, contentUrl;
let infoWindow  = {};
articles.map(article => {
infoWindow.content = `${article.snippet}`;
infoWindow.contentUrl = `${article.web_url}`;
contentForLocation = `${article.snippet}`;
contentUrl = `${article.web_url}`;
return infoWindow;
});
}
}  //addArticles

// Handle Errors
function requestError(error, part) {
console.log("Error: ", error);
}

content.then( content => {
this.state.locations[myKey].infoWindow.content = (contentForLocation);
this.state.locations[myKey].infoWindow.contentUrl = contentUrl;
this.forceUpdate()
}

)} // getInfoWindowContent
// end Nyt

filterLocations(query){
const match = new RegExp(escapeRegEx(query), 'i')
let showingLocations = this.state.locations.filter((location) => {
return match.test(location.title);
});
this.setState({
filteredLocationsOnly : showingLocations
})
}  // end filterLocations
clearQuery = () => {
this.setState({query : ''});
}
updateQuery = (query) => {
this.setState({query : query.trim()})
this.filterLocations(query);
}

render() {
return (
<div className="App">
<NeighborhoodMap
menuOpen = {this.state.menuOpen}
locations = {this.state.locations}
filteredLocationsOnly = {this.state.filteredLocationsOnly}
query = {this.state.query}
updateQuery = { (query) => {
this.updateQuery(query)
}}
clearQuery = { () => {
this.clearQuery()
}}
filterLocations = { (query) => {
this.filterLocations(query)
}}
infoWindowStatus = {this.state.infoWindowStatus}
showInfoWindowNow = { (location) => {
this.showInfoWindowNow(location)
}}
closeInfoWindowNow = { (location) => {
this.closeInfoWindowNow(location)
}}
updateInfoWindowContentAgain = { (id) => {
this.updateInfoWindowContentAgain(id)
}}
infoWindow = {this.state.infoWindow}
/>
</div>
) // return
}// render
} // Component
export default App;

您可以跳过不可变性帮助程序,而是复制locations数组,创建locations[myKey]的副本,并覆盖infoWindowStatus

const locations = [...this.state.locations];
locations[myKey] = { ...locations[myKey], infoWindowStatus: true };
this.setState({ locations });

此外,您给NeighborhoodMapinfoWindowStatus来自this.state.infoWindowStatus,但您将其存储在this.state.locations[0].infoWindowStatus.

相关内容

  • 没有找到相关文章

最新更新