Установка изменяющегося значения prop в дочернюю переменную состояния

#javascript #reactjs

#javascript #reactjs

Вопрос:

Давайте предположим, что у нас есть два компонента (родительский и дочерний), в основном я отправляю переменную состояния моих родителей в элемент ввода моего дочернего элемента для выполнения некоторых манипуляций. Что-то вроде…

  var Parent = React.createClass({
  getInitialState: function() {
    return {
      name: ''
    }
  },
  handleTextChange: function(e) {
    this.setState({
      name: e.target.value
    })
  },
  render: function() {
    return(
      <div>
      <input type="text" placeholder="Enter something" onChange={this.handleTextChange} />
      <Child name={this.state.name} />
      </div>
    )
  }
});
  

И мой дочерний компонент выглядит так..

 var Child = React.createClass({
  getInitialState: function() {
    return {
      childName: ''
    }
  },
  componentWillReceiveProps: function(nextProps) {
    this.setState({
      childName: nextProps.name
    })
  },
  handleChildTextChange: function(e) {
    this.setState({
      childName: e.target.value
    })
  },
  render: function() {
    return(
      <div>
        <input type="text" onChange={this.handleChildTextChange} placeholder={this.props.name} />
        <h4>{this.state.childName}</h4>
      </div>
    )
  }
});
  

В принципе, я хочу сделать 3 вещи

  1. Значение имени дочернего компонента моего дочернего компонента должно быть изначально установлено на значение родительского реквизита (this.props.name которая является переменной состояния родителя name )
  2. При изменении моего Child ввода целевой текст должен переопределять имя моего родителя (this.props.name )
  3. Если мой дочерний ввод пуст, а мое Parent имя меняется, я хочу, чтобы переменная состояния моего Child компонента была переменной childName изменяющегося реквизита, поступающего от родителя (this.props.name )

Может кто-нибудь, пожалуйста, помочь мне с этим?

P.S: Child целевой текст моих компонентов не должен обновлять мою Parent переменную состояния (имя) Я имею в виду, никаких обратных вызовов в качестве реквизита.

Комментарии:

1. Поскольку вы передаете его как prop, зачем заставлять его находиться внутри состояния? Просто передайте его как prop и передайте обработчик для изменения значения

2. Я добавляю его в переменную состояния, потому что при изменении моего дочернего ввода я хочу, чтобы измененное значение было присвоено переменной состояния. Кроме того, мне нужно this.props.name только при первоначальном рендеринге моего дочернего компонента.

3. Помогли три пункта, почему бы не установить дополнительное значение состояния, чтобы указать, что дочерний элемент «владеет» текущим именем, а не родительским? Я немного обновил ответ

Ответ №1:

Я думаю, вы должны установить только состояние для вашего this.props.name при получении начального значения состояния, а не на каждом компоненте, будет получен образец. Как только дочерний элемент установит свое собственное состояние, значение изменится только в дочернем элементе, а не в родительском

 var Child = React.createClass({
  getInitialState: function() {
    return {
      childName: this.props.name,
      owned: false
    }
  },
  componentWillReceiveProps: function(nextProps) {
    // only do it if the state isn't owned by the child
    if (!this.state.owned) {
      this.setState({
        childName: nextProps.name,
        owned: false
      });
    }
  },
  handleChildTextChange: function(e) {
    this.setState({
      childName: e.target.value,
      owned: true
    });
  },
  render: function() {
    return(
      <div>
        <input type="text" onChange={this.handleChildTextChange} placeholder={this.props.name} />
        <h4>{this.state.childName}</h4>
      </div>
    )
  }
});

var Parent = React.createClass({
  getInitialState: function() {
    return {
      name: ''
    }
  },
  handleTextChange: function(e) {
    this.setState({
      name: e.target.value
    })
  },
  render: function() {
    return(
      <div>
      <input type="text" placeholder="Enter something" onChange={this.handleTextChange} />
      <Child name={this.state.name} />
      </div>
    )
  }
});

ReactDOM.render(<Parent />, document.getElementById('container'));  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
</div>