简体   繁体   中英

Passing updated state as props

I'm relatively new to React and wondering if you could take a look at this problem if possible. I'm making an ajax call to an API on a click event and storing the results in the 'SearchButtons' component's state.

The state is then passed into the child component via the props. However the props in the child component ( SearchForm ) equals the previous state on the parent component and is not updated when the user clicks one of the buttons.

I'm wondering if there is a way around this, maybe updating the component before the props are sent to the child component?

import React from 'react';
import SearchForm from './SearchForm'

class SearchButtons extends React.Component {
  constructor(){
    super();
    this.state = {
      data: {}
    }
  }

  update(event){
    $.ajax({
      url: 'http://example/api/' + event.target.value,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({ data: data })
      }.bind(this)
    });
  }

  render() {
    return (
      <div>
        <button type="button" value="people" onClick={this.update.bind(this)} className="btn btn-primary">People</button>
        <button type="button" value="car" onClick={this.update.bind(this)} className="btn btn-primary">Car</button>
        <button type="button" value="planet" onClick={this.update.bind(this)} className="btn btn-primary">Planet</button>
        <SearchForm data={this.state.data} />
      </div>
    )
  }
}

export default SearchButtons

Please see example of the SearchForm component below

import React from 'react';

class SearchForm extends React.Component {

  componentWillReceiveProps(){
    console.log(this.props.data);
  }

  render(){
    return (
      <form className="form-inline">
        <div className="form-group">
          <label className="sr-only" for="exampleInputEmail3"></label>
          <input type="text" className="form-control" placeholder="Enter text..." />
        </div>
        <button type="submit" className="btn btn-default">Search</button>
      </form>
    )
  }
}

export default SearchForm

componentWillReceiveProps receives the next props as the first argument, so by logging this.state.props you are seeing the current props, not the ones that are being received.

Try to log the next ones like this:

componentWillReceiveProps(nextProps){
    console.log(nextProps.data);
}

Of course, you can also check what the new props are after they have been updated by calling the componentDidUpdate lifecycle method instead of (or alongside, if you want to monitor both steps) componentWillReceiveProps :

componentDidUpdate(prevProps, prevState) {
    console.log(this.props.data);
}

Take a look a the lifecycle methods if you want to know more!

It appears as though you're doing things correctly, and if you render some data from the props in the JSX you'll see the data update as you expect.

componentWillRecieveProps as a lifecycle method is very semantic in what it means, the component WILL receive props but hasn't yet. If you log this.props you'll see the old props. Log the next Props to see the update

componentWillReceiveProps(nextProps) {
  console.log('new props: ', nextProps);
}

This is a very good article that very concisely breaks down each stage of the component life cycle and shows you how each method works:

http://busypeoples.github.io/post/react-component-lifecycle/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM