将状态从子节点传递到父节点导致响应组件生命周期重新启动

时间:2017-05-23 21:23:08

标签: reactjs

在我的项目中,我在我的孩子SearchBar组件中填写了一个输入。

提交表单后,我想更改父组件中searchQuery属性的状态,并使用该状态进行api调用。

我将一个handleSubmit函数从父(App)组件传递给子(SearchBar)组件,并将输入值传递给该函数。然后在App组件的handleSubmit函数中,我可以将状态更改为我想要的值。

我的期望是,因为我使用了setState,这会导致render函数再次运行,然后是componentDidMount。

但是,整个React组件生命周期已重新启动,因此this.state.searchQuery始终重置为其空字符串的初始值,因此我总是搜索空字符串。

为什么React组件生命周期的所有功能都重新开始?我怎样才能解决这个问题,这样我才能将正确的值传递给componentDidMount中的api调用?

我的代码如下:

父组件(App)

import React, { Component } from 'react';
import SearchBar from "./SearchBar.js"

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      people: [],
      planets: [],
      searchQuery: ''
    }
    this.handleSubmit = this.handleSubmit.bind(this);
    console.log('in constructor. this.state.searchQuery is: ', this.state.searchQuery) //empty string
  }

  handleSubmit(event, value) {
    console.log('handle submit is called. value is: ', value);
    this.setState({
      searchQuery: value
    }, ()=> {
      console.log('this.state.searchQuery is:', this.state.searchQuery); //the value I type in
    })
  }

  componentDidMount() {
    console.log('this.state.searchQuery is: ', this.state.searchQuery) //empty string
    //make api call
   api.fetchPeople(this.state.searchQuery).then((results)=> {
     //do stuff
   }
  }

  render() {
    console.log('in render. this.state.searchQuery is: ', this.state.searchQuery) //empty string
    return (
      <div className='content'>
        <div className='logo'>
        </div>
        <SearchBar submit={this.handleSubmit} />
      </div>
    );
  }
}

export default App;

子组件(SearchBar)

import React, { Component } from 'react';
import './SearchBar.css';

class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({
      value: event.target.value
    })
  }

  handleSubmit(event) {
    this.props.submit(event, this.state.value);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit} className='search-bar'>
      <input onChange={this.handleChange} value={this.state.value} placeholder='Search Your Destiny' />
      </form>
    );
  }
}

export default SearchBar;

1 个答案:

答案 0 :(得分:1)

  

我的期望是,因为我使用了setState,这会导致render函数再次运行,然后是componentDidMount。

父(App)中的handleSubmit函数设置组件的状态,然后触发componentWillUpdate生命周期函数,而不是componentDidMount函数。

componentDidMount仅在安装组件时触发一次: https://facebook.github.io/react/docs/react-component.html#componentdidmount