Когда действительно использовать getDerivedStateFromProps? - PullRequest
0 голосов
/ 10 декабря 2018

У меня возникают проблемы с определением, действительно ли моей иерархии компонентов требуется getDerivedStateFromProps, если случаи, когда это необходимо, действительно настолько редки, насколько это звучит в документации.Это может быть фундаментальное недоразумение относительно дизайна React / Redux.

class AttributeList extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      attributes: props.attributes,
      newAttributes: []
    }
  }

  addNewAttribute = () => {
      // add new empty attribute to newAttributes state
  }

  onKeyChange = () => {
      // update appropriate attribute key
  }

  onValueChange = () => {
      // update appropriate attribute value
  }

  saveAttributes = () => {
      // save the, API call
  }

  render = () => {
      this.state.attributes.map((pair) => {
          <Attribute
            //pass data + functions, functional component />
      })
      this.state.newAttributes.map((pair) => {
          <Attribute
            //pass data + functions, functional component />
      })
  }

  static getDerivedStateFromProps(){
      // ?? do comparisons here to choose to remove or keep certain newAttributes? or just ignore result of save and keep interface as-is, just show error message if saving failed. 
  } 
}

У меня есть родительский компонент AttributeList, который отображает группу Attributes, которые по сути являются парами ключ-значение.AttributeList получает список атрибутов документа в качестве реквизита.Однако атрибуты можно редактировать, поэтому он инициализирует свое состояние (this.state.attributes) с помощью this.props.attributes.Обычно ключи являются неизменяемыми, но если пользователь добавляет новый атрибут в список, он может редактировать как ключ, так и значение.В любой момент пользователь может сохранить все атрибуты.Когда новые атрибуты сохранены, я бы хотел отключить редактирование ключей для них.Здесь дилемма.

Первый вариант - сохранить документ и просто надеяться, что он сработал, а затем очистить новый список атрибутов и отметить все атрибуты как сохраненные (отключение ввода с клавиатуры).Я думаю, что это было бы «полностью неконтролируемое» решение, когда после инициализации состояния компонент обрабатывает все самостоятельно.Тем не менее, что, если сохранить не удастся?Я не хочу показывать и неверное состояние пользователю.

Так что я хочу сделать второй вариант.После сохранения извлеките документ, который загрузит список атрибутов и повторно отобразит компонент.Однако мне нужно избавиться от моих новых атрибутов, поскольку теперь они являются частью attributes проп.Я хотел бы убедиться, что новые атрибуты на самом деле являются частью attributes реквизита.Кажется, что это произойдет в getDerivedStateFromProps, где я буду на каждом цикле рендеринга проверять, существуют ли какие-либо новые атрибутные ключи в attributes prop, и удалять их из «нового» списка, если они есть, и возвращать это состояние.

Но действительно ли это подходящее время для использования getDerivedStateFromProps?Мне кажется, что для любой страницы, которую пользователь «редактирует» что-то, где вы делаете вызов API для его сохранения, если вы хотите выполнить рендеринг на основе сохраненных данных («правда»), тогда мне нужно использовать getDerivedStateFromProps.Или, возможно, с точки зрения дизайна лучше показать сообщение, похожее на «данные не были успешно сохранены» и сохранить состояние как есть, чтобы предотвратить любую потерю данных.Я честно не уверен.

1 Ответ

0 голосов
/ 10 декабря 2018

Я не вижу, как getDerivedStateFromProps входит в это, поскольку нет никакой причины, по которой вам нужно копировать реквизит в состояние, не так ли?Когда старое значение атрибута изменяется, вы сохраняете его в хранилище с избыточностью, когда новые свойства атрибута изменяются, вы можете обновить локальное состояние (или сохранить их в другом фрагменте хранилища, или дифференцировать их другим способом).Правила обновления могут быть применены в обработчиках обновления или во время слияния при сохранении.

// dispatch redux action to update store
onOldValueChange = () => {}

// this.setState to update new value
onNewKeyChange = () => {}
onNewValueChange = () => {}

render = () => {
  this.props.attributes.map((pair) => {
    <Attribute
      //pass data + onOldValueChange, functional component />
  })
  this.state.newAttributes.map((pair) => {
    <NewAttribute
      //pass data + functions, functional component />
  })
}
...