Проблема с componentWillReceiveProps

 void componentWillReceiveProps(
  object nextProps
)

Это то, что официальная документация говорит => вызывается, когда компонент получает новые реквизиты. Этот метод не вызывается для начальной отрисовки.

Я отрисовываю компонент с реквизитом, как показано ниже в Родительском компоненте —

<ArticleDetails articleDetails={this.state.details}></ArticleDetails>

Компонент ArticleDetails имеет определенный метод componentWillReceiveProps. Согласно документации, он не должен вызываться при обновлении страницы(начальная отрисовка), но это происходит. Если причина в том, что я передаю реквизит на первом вызове, то есть ли какой-то способ, которым вы могли бы сделать это в первый раз без передачи реквизита, а затем каким-то образом передать реквизит позже?

var ArticleDetails = React.createClass({
  getInitialState: function() {
    return {author: '', tags: '', data:'', relatedArticles:{}};
  },
  componentWillReceiveProps :function(){
    console.log("i am called");
    this.setState({tags:this.props.articleDetails._id||''})
  },
  handleSubmit: function(e) {
    e.preventDefault();
   /// do something
  },
  render: function() {
    return (
      <form className="articleForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Your name"
          value={this.state.heading}
        />
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.tags}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

2 ответа

  1. В деталях статьи я проходил это.государство.детали через реквизит

    <ArticleDetails articleDetails={this.state.details}></ArticleDetails>
    

    Но при обновлении состояния в Родительском для другого компонента путем обновления этого.государство.somethingdifferent в этом случае он передает те же значения реквизита снова для всех остальных компонентов. Вот почему componentWillReceiveProps был вызван.

    https://facebook.github.io/react/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html

  2. Во-первых, вы не используете componentWillReceiveProps правильно. Метод получает следующие реквизиты. Используя это.реквизит внутри этого метода даст вам предыдущий реквизит. Например. (в псевдо-коде)

    input field initial props = Hi 
    input field update to props = Hi! 
    nextProps = Hi!
    this.props = Hi
    

    Я не думаю, что вы будете слишком довольны своей структурой кода в долгосрочной перспективе. Использование реквизита для задания состояния считается анти-шаблоном. https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html

    Почему бы не использовать реквизит напрямую?

    <input
       type="text"
       placeholder="Say something..."
       value={this.props.tags}
     />
    

    Я бы так и сделал…

    http://jsbin.com/sojaju/edit?js, выход

    var Article = React.createClass({
        getInitialState: function() {
            return { tags : 'Sports, Football'};
        },
        handleSubmit: function(e) {
            e.preventDefault();
            const { value } = e.target;
            this.setState({ tags: value });
            // send to server
        },
        handleTagChange(e) {
            const { value } = e.target;
            this.setState({ tags: value });
        },
        render: function() {
            return (
                <ArticleDetails 
                    articleDetails={this.state.tags}
                    handleSubmit={this.handleSubmit} 
                    handleTagChange={this.handleTagChange}
                />
                );
        }
    });
    
    var ArticleDetails = React.createClass({
    
      render: function() {
            const { handleTagChange, articleDetails } = this.props;
        return (
          <form className="articleForm" onSubmit={this.props.handleSubmit}>
            <input
              type="text"
              placeholder="Say something..."
                        onChange={handleTagChange}
              value={articleDetails}
            />
            <input type="submit" value="Post" />
          </form>
        );
      }
    });
    
    ReactDOM.render(<Article />, document.getElementById('app'))