为什么我的 React 组件没有随着状态更新而更新?

IT技术 javascript reactjs
2021-05-14 03:50:17

我有一个我构建的地图应用程序,它需要一些地图图标在按下按钮后出现/消失,但是当我从它的父组件传入一个新的运动属性时,我不知道如何设置它以重新渲染组件:

父加载组件:

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

简单地图组件(简化版):

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);
}

最终在这里结束从状态映射事件:

<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>
4个回答

this默认情况下,React ES6 类不会自动绑定到非React基成员方法。因此,this您函数中的上下文makeMapEvents没有正确绑定。有两种方法可以解决这个问题:

通过 ES7 属性初始化器:

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});
  })
};

通过构造函数中的绑定:

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


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

您接受参数response然后尝试使用resp哪个不是您想要的变量。

可能的原因是您的makeMapEvents()函数this在调用时没有提供正确的词法值,this.setState()因此您的代码不起作用。更改makeMapEvents()函数定义以使用箭头函数( () => {}) 并提供 this 的正确词法绑定值:

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

您的代码中还有一个错字,其中缺少右括号,如上面的注释所示

您正在组件中混合 props 和 state。Sports 应该只在 props 中,它不应该在 state 中,因为它是从父组件传入的。

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
}