反应从孩子传递道具到父母的问题

时间:2019-01-17 22:54:51

标签: reactjs parameter-passing

我是React的初学者。当我尝试将道具从孩子传递给父母时,整个应用程序都会刷新,并且状态恢复为初始状态。我的代码有问题吗?我不知道如何解决。

(ps:下面的句子仅用于说明单词的数量。请不要看。为什么我必须添加更多细节。如果我有能力知道每个细节,我已经自己解决了) / p>

父母:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      stops: [],
      legs: [],
      driver: null,

      finishedSign: false,
      stopsSign: false,
      legsSign: false,
      driverSign: false
    };
  }

  componentDidMount() {
    console.log("-DID");
    this.getStops();
    this.getLegs();
    this.getDriver();
  }

  // garentee all of data have received
  checkFinished() {
    const { stopsSign, legsSign, driverSign } = this.state;
    const mark = stopsSign && legsSign && driverSign;
    if (mark)
      this.setState({
        finishedSign: mark
      });
  }

  // GET/STOPS API
  getStops() {
    fetch("/api/stops")
      .then(res => res.json())
      .then(stops => {
        this.setState({ stops: stops, stopsSign: true }, () =>
          console.log("stops fetched !", stops)
        );
        this.checkFinished();
      });
  }

  // GET/LEGS API
  getLegs() {
    fetch("/api/legs")
      .then(res => res.json())
      .then(legs => {
        this.setState({ legs: legs, legsSign: true }, () =>
          console.log("driver fetched !", legs)
        );
        this.checkFinished();
      });
  }

  // GET/Driver API
  getDriver() {
    console.log("-DRIVER");
    fetch("/api/driver")
      .then(res => {
        return res.json();
      })
      .then(driver => {
        this.setState(
          {
            driver: driver,
            driverSign: true
          },
          () => console.log("driver fetched !", driver)
        );
        this.checkFinished();
      });
  }

// passing func
  updateDriver(driver) {
    console.log("update app!");
    alert(driver);
  }

  renderMaps() {
    return (
      <Maps
        stops={this.state.stops}
        legs={this.state.legs}
        driver={this.state.driver}
      />
    );
  }

  renderDriverController() {
    return (
      <DiverController
        legs={this.state.legs}
        driver={this.state.driver}
        update={this.updateDriver}
      />
    );
  }

  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-sm-3 col-md-3">
            {this.state.finishedSign && this.renderDriverController()}
          </div>
          <div className="col-sm-8 col-md-8">
            {
              //this.state.finishedSign && this.renderMaps()
            }
          </div>
        </div>
      </div>
    );
  }
}

export default App;

孩子:

class DriverController extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: this.props.legs,
      driver: this.props.driver
    };
  }

  handleUpdate = e => {
    const driver = null;
    driver.activeLegID = this.refs.selectedLeg.value;
    driver.legProgress = this.refs.selectedProgress.value;
    if (driver.legProgress >= 0 && driver.legProgress <= 100)
      this.props.update("test");
    else alert("out of range!");
  };

  render() {
    const { items, driver } = this.state;
    console.log("items:", items);
    return (
      <form>
        <hr />
        <label>Driver Location:</label>
        <div className="form-group">
          <select
            id="inputState"
            className="form-control"
            defaultValue={driver.activeLegID}
            ref="selectedLeg"
          >
            {items.map(item => (
              <option key={item.legID}>{item.legID}</option>
            ))}
          </select>
          <div className="input-group input-group-sm mb-3">
            <div className="input-group-prepend">
              <span className="input-group-text" id="inputGroup-sizing-sm">
                Percentage:
              </span>
            </div>
            <input
              type="number"
              className="form-control"
              defaultValue={driver.legProgress}
              ref="selectedProgress"
            />
          </div>
          <button onClick={this.handleUpdate} className="btn btn-primary">
            Submit
          </button>
          <hr />
        </div>
      </form>
    );
  }
}

export default DriverController;

2 个答案:

答案 0 :(得分:1)

尝试使用 onClick={() => this.handleUpdate}

答案 1 :(得分:0)

您不应将道具从孩子传递给父母。多数民众赞成在反模式。

您可以将父函数传递给子函数,该函数将在 子,因此更新了父项中的必需状态。

刷新问题:

我认为是因为孩子被包裹在表格内。

添加     e.preventDefault()到handleSubmit函数,以防止刷新

handleUpdate = e => {
   e.preventDefault()