React-правильное управление состоянием для строк размонтированных JSX?

у нас сумасшедшая иерархия DOM, и мы передаем JSX в реквизит, а не встраиваем детей. Мы хотим, чтобы базовый класс управлял, какие документы детей показаны, и какие дети закреплены или прикреплены к верхней части окна связанного документа.

  • список (сумасшедшая физика записывает встроенные стили в оболочки базового класса)
    1. Пользовательские Формы (передает строки JSX в базу класс)
      • Базовый Класс (подключается к списку)
    2. Пользовательские Формы (передает строки JSX в базовый класс)
      • базовый класс (подключается к списку)

проблема в том, что мы передаем глубоко вложенные JSX, а управление состоянием / доступ к ссылкам в форме-кошмар.

Я не хочу повторно объявлять каждую строку каждый раз, потому что эти строки имеют дополнительное состояние, прикрепленное к ним в базовом классе, и базовый класс должен знать, какие строки фактически изменились. Это довольно легко, если я не буду переделывать строки.


Я не знаю, как на самом деле иметь дело со строками JSX в пользовательской форме.

  1. ссылки могут быть добавлены только в подпрограмму render(). Что делать, если CustomForm хочет измерить элемент JSX или написать встроенный CSS? Как это могло JSX элемент существуют в CustomForm.состояние, но также есть ref? Я мог бы клонировать и хранить виртуальный DOM (с refs) внутри CustomForm или зависеть от базового класса для подачи глубоко вложенного, смонтированного ref обратно.
  2. Я считаю, что это плохая практика писать состояние компонента из существующего состояния. Если состояние CustomForm изменяется, и я хочу изменить, какие строки передаются в BaseClass, я должен дросселировать с shouldComponentUpdate, повторно объявите этот документ этапа (поддерживая ссылки на объект строки), затем вызовите setState в общей коллекции. this.state.stages.content[3].jsx это единственное, что изменилось, но я должен перебирать каждую строку в каждом документе этапа в BaseClass, когда он видит, что props.stages изменен.

есть ли какой-то трюк для работы с коллекциями JSX? Я делаю что-то не так? Все это кажется слишком сложным, и я бы не хотел усугублять проблему, следуя какой-то анти-схеме.


таможня Форма:

render () {
  return <BaseClass stages={this.stages()}/>
}

stages () {
  if (!this._stages) this._stages = { title: this.title(), content: this.content() };
  return this._stages;
}

title () {
  return [{
    canBeDocked: false,
    jsx: (
      <div>A title document row</div>
    )
  }
}

content () {
  return [{
    canBeDocked: false,
    jsx: (
      <div>Hello World</div>
    )
  }, {
    canBeDocked: true,
    jsx: (
      <div>Yay</div>
    )
  }
}

3 ответов


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

отличный видеокурс одного из создателей React Дэна Абрамова:начало работы с Redux


абсолютно согласен с @t1gor. Ответом для нас было использование REDUX. Это изменило всю игру для нас. Внезапно кнопка, которая вложена на 10 уровней глубже (то есть внутри основного вида, заголовка, заголовка-контейнера, левой боковой сетки и т. д., и т. д., глубже и глубже) в чисто пользовательские компоненты, имеет возможность захватить состояние, когда это необходимо.

вместо...

  • родитель (передать вниз состояние) - владеет состояние vars
    • ребенок (пройдет вниз снова) - родитель имеет государственные Варс
      • внук (пройдет в третий раз) - у дедушки и бабушки есть состояние vars
        • правнук (нуждается в этом состоянии var) - прадедушка имеет состояние vars

Вы можете сделать...

  • Parent (без передачи) - считывает глобальные состояния vars
    • ребенок
      • внук
        • правнук-также читает тот же глобальный уровень состояния vars так и не был принят...

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

'use strict'

//Importation of Connection Tools & View
import { connect } from 'react-redux';
import AppView from './AppView';


//Mapping -----------------------------------

const mapStateToProps = state => {
    return {
        someStateVar: state.something.capturedInState,
    };
}

const mapDispatchToProps = dispatch => {
    return {
        customFunctionsYouCreate: () => {
            //do something!
            //In your view component, access this by calling this.props.customFunctionsYouCreate
        },
    };
}

//Send Mappings to View...
export default connect(mapStateToProps, mapDispatchToProps)(AppView);

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


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

constructor (props) {
  super(props);

  // --- can't include refs --->
  // --- not subroutine of render --->
  this.state = {
    templateForChild: [
      <SomeComponentInstance className='hello' />,
      <AnotherComponentInstance className='world' />,
    ],
  };
}

componentDidMount () {
  this.setState({
    templateForChild: [ <div className='sometimes' /> ],
  }); // no refs for additional managing in this class
}

render () {
  return ( <OtherManagerComponent content={this.state.templateForChild} /> );
}
  1. Я считаю, что ответ может быть включить функцию обратного вызова ref, а не строку, как упоминал дан Абрамов, хотя я еще не уверен, что React все еще бросает предупреждение. Это гарантирует, что CustomForm и BaseClass назначено же ref экземпляр (при props.ref выполняется обратный вызов)

  2. ответ, вероятно, использовать key или createFragment. несвязанная статья, которая решает проблему повторного монтажа. Не уверен, что фрагмент все еще включает те же экземпляры, но статья читается таким образом. Это, вероятно, цель key, а не ref, который предназначен для поиска узла DOM (хотя и findDOMNode(ref) если !(ref instanceof HTMLElement).