Передача состояния от дочернего к родительскому компоненту

Есть ли какой-либо правильный способ получить доступ к свойству в состоянии дочернего компонента и получить его значение из родительского компонента?

У меня есть компонент под названием "itemSelection", где я отображаю через ответ api, чтобы получить некоторые элементы, подобные этому

            <div className="row">
                {this.state.items.map(i => <Item ref="item" id={i.id} name={i.name} quantity={i.quantity} />)}
            </div>

В компоненте Item есть свойство в состоянии под названием «selected», значение которого я хочу знать, было ли оно истинным или ложным в компоненте itemSelection. Я знаю, что могу передавать реквизиты из itemSelection в Item, но что, если мне нужно обратное? где я могу передать данные из Item в itemSelection


ИЗМЕНИТЬ

Итак, я создал свойство в родительском компоненте «itemSelection» под названием «selected» и установил для него значение = false = (зная, что у меня есть такое же свойство в дочернем компоненте, для которого также установлено = false =)

в дочернем компоненте я поместил эту строку в функцию обработчика событий после того, как я сделал setState для свойства, выбранного, чтобы изменить его на = true =

this.props.getPropsFromChild(this.state.selected);

затем в родительском компоненте я сделал эту функцию

getPropsFromChild = (selected) => {
      this.setState({selected: selected}); 
  }

но все равно не сработало, не знаю, правильно ли я все исправил.


person develop05    schedule 13.09.2018    source источник
comment
Для этого вам нужно использовать обратные вызовы или библиотеку управления состоянием.   -  person Hemadri Dasari    schedule 13.09.2018
comment
Как вы сказали в @ Think-Twice, вы можете использовать обратные вызовы, но это неправильный способ React. Дочерние компоненты не передают некоторое состояние родителям. Вы можете оставить это выбранное состояние в родительском. Ваш дочерний компонент только обновляет родительское состояние через обратные вызовы, не сохраняйте свое собственное состояние таким образом.   -  person devserkan    schedule 13.09.2018


Ответы (2)


Передача props от дочернего к родительскому компоненту работает с использованием функций обратного вызова в React. Или вы также можете использовать библиотеку управления состоянием, такую ​​как Redux, и хранить данные в дочернем компоненте и получать данные в родительском компоненте.

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

ItemSelection: родительский компонент

      //handler function
      getPropsFromChild = (id, name) => {
            console.log(id, name);
       }

       //pass down your handler function to child component as a prop
        <div className="row">
            {this.state.items.map(i => <Item ref="item" id={i.id} name={i.name} getPropsFromChild={this.getPropsFromChild} quantity={i.quantity} />)}
        </div>

Элемент: Дочерний компонент

componentDidMount(){
    //access handler function passed to your item component and access it using this.props and send the values as you want to the function
    this.props.getPropsFromChild(“01”, “Hi”);
}
person Hemadri Dasari    schedule 13.09.2018
comment
Большое вам спасибо за ваш ответ! это то, что я действительно искал. но работает ли это, если я хочу, чтобы все было как в реальном времени? Я имею в виду, что если я передал состояние элемента его родительскому элементу (ItemSelection), а затем сделал какое-то действие, которое изменило состояние элемента, изменится ли оно автоматически и в ItemSelection? - person develop05; 16.09.2018
comment
Решение везде одинаково, независимо от окружающей среды. Когда вы вызываете действие в дочернем компоненте, которое вы получили от родителя, и эта функция-обработчик в родительском компоненте может изменять родительское состояние, но не дочернее состояние. Сообщите мне, если это все еще не ясно - person Hemadri Dasari; 16.09.2018
comment
Скажем, предположим, что у вас есть компоненты A и B, а компонент B является дочерним по отношению к компоненту A. Компонент отображает модальное окно, а B имеет кнопку. Теперь сценарий таков, что при щелчке по Бертону в B вам нужно показать компонент Modal in A. Итак, в этом случае вам нужен обратный вызов, и у u будет функция обработчика событий, объявленная в компоненте A, и передать ее дочернему компоненту, а вы передадите ее кнопке onclick. Поэтому, когда происходит нажатие кнопки, функция обработчика событий запускается в родительском компоненте, и вы изменяете там логическое состояние, которое будет отображать модальное окно при нажатии. - person Hemadri Dasari; 16.09.2018
comment
Спасибо за ответ еще раз. Не могли бы вы проверить раздел РЕДАКТИРОВАНИЕ в моем вопросе? Я не знаю, что происходит. я думаю, это должно сработать, не так ли? это сработало, но когда я дважды нажимаю на кнопку, не с первого раза. - person develop05; 16.09.2018

Как пытался объяснить в комментариях, вы можете использовать для этого обратные вызовы, но старайтесь избегать получения такого значения от дочернего компонента. Вы можете сохранить состояние selected в родительском компоненте. Для этого вашему Item компоненту вообще не нужно сохранять состояние. С соответствующими обработчиками от родителя вы можете легко обновить свое состояние.

class App extends React.Component {
  state = {
    items: [
      { id: "1", name: "foo", quantity: 1 },
      { id: "2", name: "bar", quantity: 2  },
      { id: "3", name: "baz", quantity: 3 },
    ],
    selected: "",
  }

  handleSelect = item => this.setState({ selected: item.id })

  render() {
    const { items } = this.state;
    
    return (
      <div>
      Selected item: {this.state.selected}
      {
        items.map( item =>
          <Item key={item.id} item={item} onSelect={this.handleSelect} />
        )
      }
      </div>
    );
  }
}

const Item = props => {
  const { item, onSelect } = props;
  const handleSelect = () => onSelect( item );
  
  return (
    <div style={{border: "1px solid gray"}} onClick={handleSelect}>
      <p><strong>Item id:</strong> {item.id}</p>
      <p><strong>Item name</strong>: {item.name}</p>
      <p><strong>Item quantity</strong>: {item.quantity}</p>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

person devserkan    schedule 13.09.2018