Я думаю, я бы справился с этим так...
В контейнере или компоненте верхнего уровня создайте массив для хранения сносок. Затем передайте этот массив в качестве реквизита любому компоненту, который может отображать сноски, а также компоненту, отображающему сноски, который должен отображаться после любого из других компонентов.
const DocComponent = () => {
const footnotes = [];
return (
<div>
<SomeContent footnotes={footnotes} />
<SomeOtherContent footnotes={footnotes} />
<EvenDifferentContent footnotes={footnotes} />
<Footnotes footnotes={footnotes} />
</div>
);
};
Обратите внимание, что массив сносок должен передаваться вниз по иерархии через реквизиты всем компонентам, которые могут отображать ссылку на сноску. Каждый раз, когда компонент отображает ссылку на сноску, он добавляет сноску в массив следующим образом:
const SomeContent = ({footnotes}) => {
footnotes.push('This is the footnote text.');
const footnoteIndex = footnotes.length;
return (<p>Hermansen and Shihipar, et al [{footnoteIndex}]</p>);
};
Когда выполнение достигает компонента Footnotes, тот же самый экземпляр массива сносок будет передан ему через свойство. В этот момент выполнения массив будет заполнен всеми сносками, которые необходимо отобразить. И вы можете просто визуализировать их простым способом:
const Footnotes = ({footnotes}) => {
const inner = footnotes.map(
(footnote, index) => (<li>[{index+1}] {footnote}</li>) );
return (<ul>{inner}</ul>);
};
Эта реализация определенно связана с порядком рендеринга компонентов. Таким образом, порядок компонентов в вашем рендеринге должен соответствовать визуальному порядку, в котором вы хотите, чтобы сноски отображались.
Вот jsfiddle - https://jsfiddle.net/69z2wepo/79222/
person
Erik Hermansen
schedule
22.05.2017