代码之家  ›  专栏  ›  技术社区  ›  Bomber

从选择列表中响应JS更新状态

  •  0
  • Bomber  · 技术社区  · 6 年前

    我有一个 react-select 组件中的选项 axios GET 我想要我的 Car 组件,用于在选择选项时显示存储在组件状态下的URL中的图像。

    我正在使用 componentDidMount componentDidUpdate 然而,在 组件更新 , this.getImage(capID); 不停地射击,我怎么能阻止这种情况,并唤起它一次?

    import React from "react";
    import axios from "axios";
    import { Panel } from "react-bootstrap";
    
    export default class CarList extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          imageSrc: ""
        };
    
        this.getImage = this.getImage.bind(this);
      }
      getImage(id) {
        axios
          .get(`xxx${id}`)
          .then(response => {
            this.setState({
              imageSrc: response.data.url
            });
          })
          .catch(error => {
            console.log(error);
          });
      }
    
      componentDidMount() {
        const {
          agrNo,
          balloon,
          bpid,
          capID,
          dealer,
          derivative,
          id,
          make,
          model,
          name
        } = this.props.car;
    
        this.getImage(capID);
      }
      componentDidUpdate() {
        const {
          agrNo,
          balloon,
          bpid,
          capID,
          dealer,
          derivative,
          id,
          make,
          model,
          name
        } = this.props.car;
    
        this.getImage(capID);
      }
    
      render() {
        let car = this.props.car;
    
        const {
          agrNo,
          balloon,
          bpid,
          capID,
          dealer,
          derivative,
          id,
          make,
          model,
          name
        } = this.props.car;
    
    
    
        return (
          <div className="car-details">
            <Panel header={name}>
              <div className="flex-container">
                <div className="flex-item">
                  {this.state.imageSrc && (
                    <img
                      src={this.state.imageSrc}
                      alt={model}
                      className="car-details__image"
                    />
                  )}
                </div>
                <div className="flex-item">
                  <p>{car.Plot}</p>
                  <div className="car-info">
                    <div>
                      <span>Genre:</span> {car.Genre}
                    </div>
                  </div>
                </div>
              </div>
            </Panel>
          </div>
        );
      }
    }
    

    应用程序:

    import React, { Component } from "react";
    import logo from "./logo.svg";
    import axios from "axios";
    import { Alert } from "react-bootstrap";
    import AsyncSelect from "react-select/lib/Async";
    import CarList from "./CarList";
    import "react-select/dist/react-select.css";
    import "./App.css";
    
    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          car: {}
        };
      }
    
      getCars(e) {
        return axios
          .get(`xxx${e}`)
          .then(response => {
            var arr = [];
            if (response.data !== undefined) {
              var searchResults = response.data.length;
              for (var i = 0; i < searchResults; i++) {
                arr.push({
                  label: `${response.data[i].name} - ${response.data[i].id}`,
                  value: response.data[i].id
                });
              }
            }
            return {
              options: arr
            };
          })
          .catch(error => {
            console.log(error);
          });
      }
    
      getCar(e) {
        axios
          .get(`xxx}`)
          .then(response => {
            this.setState({
              car: response.data
            });
          })
          .catch(error => {
            console.log(error);
          });
      }
    
      render() {
        const {
          car: { id }
        } = this.state;
        return (
          <div className="container">
            <AsyncSelect
              name="carOwner"
              value="ABC"
              cacheOptions
              defaultOptions
              loadOptions={this.getCars}
              onChange={this.getCar.bind(this)}
            />
    
            {id ? (
              <CarList car={this.state.car} />
            ) : (
              <Alert bsStyle="info">
                <p>Enter a surname above to begin...</p>
              </Alert>
            )}
          </div>
        );
      }
    }
    
    export default App;
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Sergio Moura    6 年前

    componentDidUpdate 任何时候都会开火 任何 此组件的属性或状态已更改(签出 official docs 更多信息)。

    你在改变里面的状态 getImage(id) 函数,每次发生这种情况, 组件更新 函数将在您的情况下激发,这将调用 getImage 再次运行,这将成为一个无限循环。

    你需要检查一下 capID 道具已更改,以决定是否应再次拨打电话:

    componentDidUpdate(oldProps) {
        const {
          agrNo,
          balloon,
          bpid,
          capID,
          dealer,
          derivative,
          id,
          make,
          model,
          name
        } = this.props.car;
    
        const oldCapID = oldProps.capID;
    
        if (capID !== oldCapID) {
          this.getImage(capID);
        }
    }