Я создаю приложение для текстового редактора в React. Моя базовая c структура
модель
class TextLine {
text: string
folded: boolean
indentLevel: number
index: number
model: TextEntryModel
fold: () => this.model.foldLineAtIndex(this.index)
}
class TextModel {
lines: TextLine[]
setText: (text: string) => void // splits the text, creates TextLine objects and sets each line's model to this (line.model = this)
foldLineAtIndex = (index: number) => {
// we're actually folding all the "children" of this line.
const startingLine = this.getLineAtIndex(index);
let previousIndentLevel = startingLine.indentLevel;
// start with the next line
for (let i = index + 1; i < this.lines.length; i++) {
const thisLine = this.lines[i];
if (thisLine.indentLevel > previousIndentLevel) {
thisLine.folded = true;
} else {
return; // if we've reached a line with the same indent level, we're done.
}
}
};
}
базовая c структура компонентов
<App> // state = { model: new TextEntryModel() };
{ model.lines.map(line =>
<Line
line={line}
onClick={line.fold}
/>
)}
</App>
Что-то в этом роде, это большое сокращение. Когда вы щелкаете аксессуар Line
(не в моем эскизе), он вызывает fold
на line
.
Нажатие на линию действительно меняет линии в модели, я могу это подтвердить. Но строки не переопределяются с их новым значением folded
. Сначала у меня просто было model
в качестве свойства экземпляра класса App
, и я подумал, что, возможно, перемещение его в состояние App
поможет, но без кубиков.
Я думаю, вопрос Реакта "реквизит изменился?" не утвердительно, когда изменилось свойство собственности государства. (Я надеюсь, что когда model
будет изменен, он пропустит Line
новый line
реквизит, но, возможно, model
не будет зарегистрирован как изменение).
Итак, я мог бы сделать это с Redux возможно, с редуктором, тип которого просто { model: TextModel }
, и используйте селекторы для детализации каждого Line
, или, возможно, с редуктором с простым типом TextLine[]
(или {lines: TextLine[]}
).
Но Мне нравится идея использования реальной модели с задницей. Я думаю, что именно так я и поступил бы, правильно, скажем, Swift или Angular, но, насколько я могу судить, это не соответствует парадигме React, что кажется странным. Итак, я представляю, что что-то упускаю.
Как мне go об этом?