javascript - 无法从渲染返回调用访问状态 - 'Cannot read property ' instructionList' of null'

标签 javascript reactjs react-google-maps

我正在自学 React,同时从事一个使用 react-google-maps 的项目包以生成从 A 到 B 方向的 map 。 map 本身工作正常,但我现在尝试通过 return 方法在 html 中打印相应的路线方向,但无法打印这些说明。

根据我通过 Google 和 StackOverflow 的研究,我认为我的问题可能是:

  1. 尝试访问我的 instructionList 时“this”关键字的范围在返回方法中。在这种情况下 - 我需要输入什么才能访问我的 instructionList <li> 的数组项目? 我也试过 <ol>{DirectionsService.route.state.instructionList}</ol><ol> and {DirectionsComponent.DirectionsService.route.state.instructionList}</ol>这也不起作用

  2. 加载页面时,不一定收到 api 响应,因此我的 instructionList为空且无法呈现。在哪种情况下——应该如何处理?

  3. 在我的语法中还有一些我不知道的东西(我是一个非常初学者的 react ,以及 react-google-maps 包!)

在我的代码中,我在 state 中定义了一个名为 instructionList 的数组,其中包含从 A 到 B 的指令

if (status === google.maps.DirectionsStatus.OK) {
  this.setState({
    directions: { ...result },
    markers: true
  });
  this.setState({
    instructions: this.state.directions.routes[0].legs[0].steps
  });
  this.setState({
    instructionList: this.state.instructions.map(instruction => {
      return <li>instruction.instructions</li>;
    })
  });
}

然后我试图在类返回方法中访问这个数组 - 但错误消息是说 instructionList未定义。

return (
  <div>
      <DirectionsComponent/>
      <div className="route instructions">
        <h1>{title}</h1>
        <ol>{this.state.instructionList}</ol>
      </div>
      <NotificationContainer />
  </div>

如果可以更轻松地识别问题,下面是一段更完整的代码。

class MyMapComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const {
      startLat,
      startLng,
      finishLat,
      finishLng,
      transportMode,
      title
    } = this.props;

    const DirectionsComponent = compose(
      withProps({
        googleMapURL:
          "https://maps.googleapis.com/maps/api/js?key=APIKEYGOESHERE", //removed=&callback=initMap
        loadingElement: <div style={{ height: `400px` }} />,
        containerElement: <div style={{ width: `100%` }} />,
        mapElement: <div style={{ height: `400px`, width: `400px` }} />
      }),
      withScriptjs,
      withGoogleMap,
      lifecycle({
        componentDidMount() {
          const DirectionsService = new google.maps.DirectionsService();

          DirectionsService.route(
            {
              origin: new google.maps.LatLng(startLat, startLng),
              destination: new google.maps.LatLng(finishLat, finishLng),
              travelMode: google.maps.TravelMode[transportMode],
              provideRouteAlternatives: true
            },
            (result, status) => {
              if (status === google.maps.DirectionsStatus.OK) {
                this.setState({
                  directions: { ...result },
                  markers: true
                });
                this.setState({
                  instructions: this.state.directions.routes[0].legs[0].steps
                });
                this.setState({
                  instructionList: this.state.instructions.map(instruction => {
                    return <li>instruction.instructions</li>;
                  })
                });
              } else {
                console.error(
                  `There was an error fetching directions for the specified journey ${result}`
                );
                NotificationManager.error(
                  "Journey cannot be retrieved, please try again",
                  "Error",
                  20000
                );
              }
            }
          );
        }
      })
    )(props => (
      <GoogleMap defaultZoom={3}>
        {props.directions && (
          <DirectionsRenderer
            directions={props.directions}
            suppressMarkers={props.markers}
          />
        )}
      </GoogleMap>
    ));
    return (
      <div>
        <DirectionsComponent />
        <div className="route instructions">
          <h1>{title}</h1>
          <ol>{this.state.instructionList}</ol>
        </div>
        <NotificationContainer />
      </div>
    );
  }
}
export default MyMapComponent;

当前错误信息是TypeError: Cannot read property 'instructionList' of null

我已经尝试过代码并进行了大量研究,但我正在兜圈子。我确信该解决方案是一个快速的解决方案,但由于我对 React/react-google-maps 的了解有限,我很难找到它,所以我非常感谢任何能够提供帮助的人:)

最佳答案

您还没有初始化组件的状态。所以你不能访问 state 的属性。您需要在 constructor 中初始化它。

 constructor(props){
    super(props);
    this.state = { instructionList: [] };
  }

已更新

您需要定义onChangeInstructionList 来更改MyMapComponentinstructionList inside DirectionsComponent。您还需要将 DirectionsComponent 移动到 MyMapComponentcomponentDidMount 以避免由于状态更改而导致无限循环。

class MyMapComponent {
  constructor(props){
    super(props);
    this.state = {
      instructionList: [],
    };

    this.onChangeInstructionList = this.onChangeInstructionList.bind(this);
  }

  componentDidMount() {
    const {startLat, startLng, finishLat, finishLng, transportMode} = this.props;
    const DirectionsComponent = compose(
      withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?key=APIKEYGOESHERE",//removed=&callback=initMap
        loadingElement: <div style={{ height: `400px` }} />,
        containerElement: <div style={{ width: `100%` }} />,
        mapElement: <div style={{height: `400px`, width: `400px` }}  />,
        onChangeInstructionList: this.onChangeInstructionList,
      }),
      withScriptjs,
      withGoogleMap,
      lifecycle({
        componentDidMount() {
          const DirectionsService = new google.maps.DirectionsService();

          DirectionsService.route({
            origin: new google.maps.LatLng(startLat, startLng),
            destination: new google.maps.LatLng(finishLat, finishLng),
            travelMode: google.maps.TravelMode[transportMode],
            provideRouteAlternatives: true
          }, (result, status) => {

            if (status === google.maps.DirectionsStatus.OK) {
              this.setState({
                directions: {...result},
                markers: true
              })
              this.setState({instructions: this.state.directions.routes[0].legs[0].steps});
              this.props.onChangeInstructionList(this.state.instructions.map(instruction => {
                return (<li>instruction.instructions</li>);
              }));
            } else {
              console.error(`There was an error fetching directions for the specified journey ${result}`);
              NotificationManager.error("Journey cannot be retrieved, please try again", "Error", 20000);
            }
          });
        }
      })
    )(props =>
      <GoogleMap
        defaultZoom={3}
      >
        {props.directions && <DirectionsRenderer directions={props.directions} suppressMarkers={props.markers}/>}
      </GoogleMap>
    );

    this.setState({
      DirectionsComponent,
    })
  }

  onChangeInstructionList(newList) {
    this.setState({
      instructionList: newList,
    });
  }

  render() {
    const {title} = this.props;
    const { DirectionsComponent, instructionList } = this.state;
    return (
      <div>
        <DirectionsComponent/>
        <div className="route instructions">
          <h1>{title}</h1>
          <ol>{instructionList}</ol>
        </div>
        <NotificationContainer />
      </div>

    )
  }
}
export default MyMapComponent

关于javascript - 无法从渲染返回调用访问状态 - 'Cannot read property ' instructionList' of null',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57342959/

相关文章:

reactjs - Semantic UI React - Table - 使整行可选择并链接到某处

javascript - Pug JS 变量传递

javascript - 无法正确包裹元素 anchor 标记

javascript - 基于 d3 树的图表的 Angular 指令中的数据突变

javascript - 未使用的 div 出现在 React 谷歌地图上,我无法设置它的样式

javascript - React - 数组迭代 : "' l' is not defined"error when an array is iterated

javascript - 如何在延迟加载网页上单击 'Show More' 按钮

javascript - React 不替换 div 中的内容

javascript - 开 Jest : Add component children elements to snapshot