状态更改时,React组件未更新

时间:2018-04-11 21:26:13

标签: reactjs components state

我有一个输入,等待一个URL和一个下拉列表。根据URL,下拉列表中的列表将有所不同。 我为下拉列表创建了一个组件(LocationSelector)。加载页面时输入为空。

我的问题是,当我在输入中放入一个URL并且状态数据得到更新时,该组件不会更新。

以下是处理输入的页面代码(我剪切了一些部分):

import React, { Component } from "react";
import LocationSelector from "../component/location-selector";

class Manage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      ProductURL: ""
    };

    this.handleChange = this.handleChange.bind(this);
    this.addProduct = this.addProduct.bind(this);
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  addProduct(event) {
    // Do stuff
  }

  render() {
    return (
      <div className="col-md-6">
            <div className="row">
              <div className="col-md-12">
                <h2 className="bottom-separator">Add a product</h2>
              </div>

              <form onSubmit={this.addProduct}>
                <div className="col-md-12 margin-bottom-10">
                  <label>URL :</label>
                  <input
                    type="text"
                    className="form-control"
                    name="ProductURL"
                    value={this.state.ProductURL}
                    onChange={this.handleChange}
                  />
                </div>
                <div className="col-md-12 margin-bottom-10">
                  <LocationSelector
                    label="Shop"
                    location={this.state.ProductURL.split(".")[1]}
                  />
                </div>
                <div className="col-md-12">
                  <input
                    type="submit"
                    value="Submit"
                    className="btn btn-primary"
                  />
                </div>
              </form>
            </div>
          </div>
    );
  }
}

这是我的组件LocationSelector的代码:

import React, { Component } from "react";

var data = require("../service/data");

class MySelectOptions extends Component {
  /**
   * Returns an Option element containing an ActorLocation to put in a Select element.
   * @props :
   *  -data.id : the id of the ActorLocation (ex : "5001")
   *  -data.value : the name of the ActorLocation (ex : "NY")
   *  -data.subvalue : the subtext of the ActorLocation (ex : "subtext")
   */

  render() {
    return (
      <option
        data-subtext={this.props.data.subvalue}
        value={this.props.data.id}
      >
        {this.props.data.value}
      </option>
    );
  }
}

class LocationSelector extends Component {
  /**
   * Returns a dropdown menu filled with the ActorLocation of a specific Actor.
   * @props :
   *  -label : the name of the Actor written in a normal way (ex : "My Actor")
   *  -location : the name of the Actor to be put in the URL request (ex : "myactor")
   */

  constructor(props) {
    super(props);

    this.state = {
      locations: []
    };
    this.componentDidMount = this.componentDidMount.bind(this);
    this.componentWillUnmount = this.componentWillUnmount.bind(this);
  }

  componentDidMount() {
    let vm = this;

    this.request = data.actors.get(vm.props.location).then(function(data) {
      var items = [];
      if (!jQuery.isEmptyObject(data)) {
        data.locations.forEach(function(location) {
          items.push({
            id: location.id,
            value: location.name,
            subvalue: location.subText
          });
        });
      }
      vm.setState({ locations: items });
      $(".selectpicker").selectpicker("refresh");
    });
  }

  componentWillUnmount() {
    if (this.request) {
      this.request.cancel();
    }
  }

  render() {
    var i = 0;
    var mySelectOptions = function(result) {
      return <MySelectOptions key={i++} data={result} />;
    };

    let selectId = "locationSelector" + this.props.label.replace(" ", "");

    return (
      <div>
        <label htmlFor="products">{this.props.label}:</label>
        <select
          id={selectId}
          className="selectpicker show-tick"
          data-live-search="true"
          data-size="5"
        >
          {this.state.locations.map(mySelectOptions)}
        </select>
      </div>
    );
  }
}

export default LocationSelector;

感谢您的帮助!

修改

以下是CodeSandbox中的一项工作:https://codesandbox.io/s/m4x04mw3wx

1 个答案:

答案 0 :(得分:1)

您需要使用React生命周期更新方法来执行该操作。请参阅:https://reactjs.org/docs/react-component.html#the-component-lifecycle

在LocationSelector类中添加:

componentWillReceiveProps(newProps){
    this.setState({
        location: newProps.location
    })
}