Почему родительские реквизиты не равны дочернему состоянию, когда дочернее состояние фактически ссылается на реквизиты родительского - PullRequest
0 голосов
/ 30 мая 2018

Я передаю реквизиты из родительского компонента в состояние Child, но они не синхронизированы.

То, что я пробовал:

  1. Обновления состояний могут быть асинхронными Я позаботился об этом, используя обратный вызов вместо возврата объекта.
  2. Объекты передаются по ссылке , но я использовал строку:

Я использую синтаксис React 16 и es6

class Parent extends React.Component {
  state = {
   isHidden: false
  }
  render() {
   console.log('PROPS from PARENT', this.state.isHidden)
   return <div>
     <Child isOpen={this.state.isHidden} />
     <button onClick={this.toggleModal}>Toggle Modal</button>
    </div>
   }
  toggleModal = () => this.setState(state => ({isHidden: !state.isHidden}))
 }

class Child extends React.Component {
  state = {
   isHidden: this.props.isOpen
  }
  render() {
    console.log('STATE of CHILD:',this.state.isHidden)
    return <p hidden={this.state.isHidden}>Hidden:{this.state.isHidden}</p>
  }
}
ReactDOM.render(<Parent/>, document.getElementById('app'));

Здесь кодовая ручка PEN - обратите внимание, что отображаемый элемент должен быть скрыт на основе состояния (состояние зависит от реквизита от родителя)

console shows my props and state are not equal

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

Хотя другие ответы заставят код работать, на самом деле есть более элегантное решение:)

Вашему дочернему компоненту не нужно никакого состояния, так как состояние управляется Родителем (который управляет * 1003).* имущество и передает его ребенку).Поэтому дочерний компонент должен заботиться только о подпорках.

Попробуйте написать такой компонент, и я считаю, что он должен работать:

class Child extends React.Component {
  render() {
    return <p hidden={this.props.isHidden}>Hidden:{this.props.isHidden}</p>
  }
}

Дэн Абрамов, который работает в команде React, написал в Твиттере об этой проблеме.- по сути говоря, вы должны подумать о том, можете ли вы просто использовать реквизит, прежде чем использовать состояние в компоненте https://twitter.com/dan_abramov/status/979520339968516097?lang=en

0 голосов
/ 30 мая 2018

Используйте componentWillReceiveProps, который вызывается, когда происходят изменения в props.

class Child extends React.Component {
    state = {
        isHidden: this.props.isOpen
    }
    componentWillReceiveProps(props) {

        if (props.isOpen != this.state.isHidden)
            this.setState({
                isHidden: props.isOpen
            })

    }
    render() {
        console.log('STATE of CHILD:', this.state.isHidden)
        return <p hidden = {
            this.state.isHidden
        } > Hidden: {
            this.state.isHidden
        } < /p>
    }
}
0 голосов
/ 30 мая 2018

Состояние вашего ребенка не меняется с изменением реквизита, так как компонент не знает ничего об изменении состояния в вашем конструкторе.Это распространенная ошибка, когда вы полагаетесь на свои реквизиты, чтобы построить свое местное государство.Вы можете использовать componentWillReceiveProps, как показано в ответе @Nishant Dixit.Но, начиная с React 16.3, у нас есть функция getDerivedStateFromProps (метод lifecylce) для этого.

static getDerivedStateFromProps( props, state) {
    if( props.isOpen === state.isHidden) {
      return null;
    }
    return {
      isHidden: props.isOpen,
    }
  }

Здесь мы сравниваем нашу опору и состояние, если есть изменение, мы возвращаем желаемое состояние.Нет необходимости использовать this.setState.

Связанное сообщение об изменении API в блоге, включая асинхронное отображение: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

0 голосов
/ 30 мая 2018

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

Если выЕсли вы хотите использовать состояние в дочернем элементе, настройки конструктора недостаточно, вам нужно установить дочернее состояние при изменении параметров.

Console.log является асинхронным, поэтому вы не можете полагаться на него здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...