Why is my react component not updating with state updates?

蹲街弑〆低调 提交于 2021-02-18 10:15:26

问题


I have a map app I built that requires some map icons to appear/disappear after a button press, but I can't figure out how to set it to re-render the component when I pass in a new sports property from it's parents component :

Parent loads component:

<SimpleMap sports=[default value and future values go here] />

Simple map component(simplified):

constructor(props) {
  (props);
  this.state = {
    events: [{venue: {lat: 2, lon: 1}}],
    sports: ["baseball", "football",  "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"]
  };
};

componentWillReceiveProps (nextProps) {
  this.setState({events: [{venue: {lat: 2, lon: 1}}],
                  sports: nextProps.sports});
  console.log(nextProps.sports);
}

static defaultProps = {
  center: {lat: 36.160338, lng: -86.778780},
  zoom: 12,
  sports: ["baseball", "football",  "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"],
};

makeMapEvents (insertProps) {
  fetch("./json/meetup.json").then((response) => {
    return response.json()
  }).then((response) => {
    /* eventually returns new events object based on insertProps */
    this.setState({events: response});
  }
};

componentDidMount () {
  this.makeMapEvents(this.state.sports);
  console.log("mounted", this.state.sports);
}

Eventually ends up here to map events from state:

<GoogleMap>
  {this.state.events.map((result) => {
     return (<Marker key={counter++} lat={result.venue.lat} lng={result.venue.lon} 
                sport={this.props.sport} data={result}/>);
  })}
</GoogleMap>

回答1:


React ES6 classes do not autobind this by default to non-react base member methods. Therefore, the context for this in your function makeMapEvents is not bound correctly. There are 2 ways to fix this:

Via ES7 property initializer:

makeMapEvents = (insertProps) => {
  fetch("./json/meetup.json").then((response) => {
    return response.json()
  }).then((response) => {
    /* eventually returns new events object based on insertProps */
    this.setState({events: response});
  })
};

Via binding in constructor:

constructor(props) {
  (props);
  this.state = {
    events: [{venue: {lat: 2, lon: 1}}],
    sports: ["baseball", "football",  "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"]
  };

  this.makeMapEvents = this.makeMapEvents.bind(this) // << important line


}



回答2:


.then((response) => {
    this.setState({events: resp});
}

You take in parameter response then try to use resp which isnt the variable you want.




回答3:


The probable cause is that your makeMapEvents() function doesn't provide the correct lexical value of this when calling this.setState() and as a result your code doesn't work. Change the makeMapEvents() function definition to use Arrow function (() => {}) and provide correct lexically bound value of this as:

makeMapEvents = (insertProps) => {
  fetch("./json/meetup.json").then((response) => {
    return response.json()
  }).then((response) => {
    this.setState({events: response});
  }); // <-- Typo here. The closing parenthesis is missing
};

Also there is a typo in your code wherein the closing parenthesis is missing as shown in comments above




回答4:


You are mixing up props and state in the component. sports should only be in props, it shouldn't be in state as it is being passed in from the parent component.

constructor(props) {
  (props);
  this.state = {
    events: [{venue: {lat: 2, lon: 1}}] <== removed sports here, it didn't belong
};

componentWillReceiveProps (nextProps) {
  this.setState({events: [{venue: {lat: 2, lon: 1}}],
                  sports: nextProps.sports});
  console.log(nextProps.sports);
}

static defaultProps = {
  center: {lat: 36.160338, lng: -86.778780},
  zoom: 12,
  sports: ["baseball", "football",  "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"],
};

makeMapEvents (insertProps) {
  fetch("./json/meetup.json").then((response) => {
    return response.json()
  }).then((response) => {
    /* eventually returns new events object based on insertProps */
    this.setState({events: response});
  }
};

componentDidMount () {
  this.makeMapEvents(this.props.sports);  <== changed to props.sports
  console.log("mounted", this.props.sports); <== changed to props.sports
}


来源:https://stackoverflow.com/questions/38196017/why-is-my-react-component-not-updating-with-state-updates

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