在 ReactJS 中创建动态 table 内容
Creating dynamic table of contents in ReactJS
我有一个组件代表一个页面,该页面有多个 SectionHeader 组件作为该页面的子组件。我想通过检查作为 SectionHeaders 的 Page 子项来动态创建 table 内容。
<Page>
<TaleOfContents sections={this.props.children} />
<SectionHeader title={"Section A"} />
<TextBlock>
<p> Text here. </p>
</TextBlock>
<SectionHeader title={"Section B"} />
<TextBlock>
<p> Text here. </p>
</TextBlock>
</Page>
不幸的是,this.props.children
未定义。有没有办法动态获取 Page 的这些子项并在 TableOfContents 中呈现它们?
编辑:这是我的页面组件。它实际上只是一个将一堆其他组件捆绑在一起的大型渲染方法。
/** @jsx React.DOM */
var React = require('react/addons');
// COMPONENTS
var TextBlock = require('../text_block.jsx');
var PaperHeader = require('../header_paper.jsx')
var SectionHeader = require('../header_section.jsx');
var TableOfContents = require('../table_of_contents.jsx');
var Page = React.createClass({
render: function() {
return (
<div>
<PaperHeader
title={"Page Title"}
authors={["Cole Gleason"]}
/>
<SectionHeader
title={'First Section'}
size={'large'}
/>
<TextBlock
key={"text_first"}
>
<p>
Text goes here.
</p>
</TextBlock>
<this.props.activeRouteHandler/>
</div>
);
}
});
module.exports = Page;
您可以将内部组件放在一个数组中,遍历它们然后渲染它们。像这样:
var React = require('react/addons');
// COMPONENTS
var TextBlock = require('../text_block.jsx');
var PaperHeader = require('../header_paper.jsx')
var SectionHeader = require('../header_section.jsx');
var TableOfContents = require('../table_of_contents.jsx');
var Page = React.createClass({
render: function() {
var contents = [
<PaperHeader title={"Page Title"} authors={["Cole Gleason"]} />,
<SectionHeader title={'First Section'} size={'large'} />,
<TextBlock key={"text_first"}>
<p>
Text goes here.
</p>
</TextBlock>,
<this.props.activeRouteHandler/>
];
var titles = contents.map(function(item) {
if (item.title && some_other_requirement) {
return item.title;
}
return undefined;
});
return (
<div>
<TOC titles={titles} />
{contents}
</div>
);
}
});
module.exports = Page;
但是 我忍不住觉得你并没有以正确的理由和正确的方式使用 React。您将 React 组件视为简单的模板。这样的事情更有意义:
var React = require('react/addons');
// COMPONENTS
var Page = require('../Page.jsx');
var Section = require('../Section.jsx');
var TextBlock = require('../TextBlock.jsx');
var App = React.createClass({
render: function() {
return (
<Page title='Page title'>
<Section title='Section title'>
<TextBlock>
<p>Text goes here</p>
</TextBlock>
<TextBlock>
<p>Text goes here</p>
</TextBlock>
</Section>
<this.props.activeRouteHandler />
</Page>
);
}
});
module.exports = App;
给事物正确的结构很重要。我认为这更有意义,因为现在 parent 和 children 之间存在真正的关系。属于某个部分的 TextBlock 应位于该部分内。现在这并不能解决您的 table 内容问题,但这是一个开始。例如,现在 Page
的所有直接 children 都是 Sections
,因此您可以用它做更多事情。
如果您想在运行时构建真正动态的 table 内容,您应该寻找另一个地方来存储您的内容。您现在正在将模板与内容混合在一起,这并不理想。 React 组件中的通信实际上只有一种方式(沿着树向下),因此尝试将数据从组件传回同级组件或 parent 并不容易,也不是一个好主意。查看 Flux 以了解有关数据应如何流动的更多信息。
另一个好读物:https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
我有一个组件代表一个页面,该页面有多个 SectionHeader 组件作为该页面的子组件。我想通过检查作为 SectionHeaders 的 Page 子项来动态创建 table 内容。
<Page>
<TaleOfContents sections={this.props.children} />
<SectionHeader title={"Section A"} />
<TextBlock>
<p> Text here. </p>
</TextBlock>
<SectionHeader title={"Section B"} />
<TextBlock>
<p> Text here. </p>
</TextBlock>
</Page>
不幸的是,this.props.children
未定义。有没有办法动态获取 Page 的这些子项并在 TableOfContents 中呈现它们?
编辑:这是我的页面组件。它实际上只是一个将一堆其他组件捆绑在一起的大型渲染方法。
/** @jsx React.DOM */
var React = require('react/addons');
// COMPONENTS
var TextBlock = require('../text_block.jsx');
var PaperHeader = require('../header_paper.jsx')
var SectionHeader = require('../header_section.jsx');
var TableOfContents = require('../table_of_contents.jsx');
var Page = React.createClass({
render: function() {
return (
<div>
<PaperHeader
title={"Page Title"}
authors={["Cole Gleason"]}
/>
<SectionHeader
title={'First Section'}
size={'large'}
/>
<TextBlock
key={"text_first"}
>
<p>
Text goes here.
</p>
</TextBlock>
<this.props.activeRouteHandler/>
</div>
);
}
});
module.exports = Page;
您可以将内部组件放在一个数组中,遍历它们然后渲染它们。像这样:
var React = require('react/addons');
// COMPONENTS
var TextBlock = require('../text_block.jsx');
var PaperHeader = require('../header_paper.jsx')
var SectionHeader = require('../header_section.jsx');
var TableOfContents = require('../table_of_contents.jsx');
var Page = React.createClass({
render: function() {
var contents = [
<PaperHeader title={"Page Title"} authors={["Cole Gleason"]} />,
<SectionHeader title={'First Section'} size={'large'} />,
<TextBlock key={"text_first"}>
<p>
Text goes here.
</p>
</TextBlock>,
<this.props.activeRouteHandler/>
];
var titles = contents.map(function(item) {
if (item.title && some_other_requirement) {
return item.title;
}
return undefined;
});
return (
<div>
<TOC titles={titles} />
{contents}
</div>
);
}
});
module.exports = Page;
但是 我忍不住觉得你并没有以正确的理由和正确的方式使用 React。您将 React 组件视为简单的模板。这样的事情更有意义:
var React = require('react/addons');
// COMPONENTS
var Page = require('../Page.jsx');
var Section = require('../Section.jsx');
var TextBlock = require('../TextBlock.jsx');
var App = React.createClass({
render: function() {
return (
<Page title='Page title'>
<Section title='Section title'>
<TextBlock>
<p>Text goes here</p>
</TextBlock>
<TextBlock>
<p>Text goes here</p>
</TextBlock>
</Section>
<this.props.activeRouteHandler />
</Page>
);
}
});
module.exports = App;
给事物正确的结构很重要。我认为这更有意义,因为现在 parent 和 children 之间存在真正的关系。属于某个部分的 TextBlock 应位于该部分内。现在这并不能解决您的 table 内容问题,但这是一个开始。例如,现在 Page
的所有直接 children 都是 Sections
,因此您可以用它做更多事情。
如果您想在运行时构建真正动态的 table 内容,您应该寻找另一个地方来存储您的内容。您现在正在将模板与内容混合在一起,这并不理想。 React 组件中的通信实际上只有一种方式(沿着树向下),因此尝试将数据从组件传回同级组件或 parent 并不容易,也不是一个好主意。查看 Flux 以了解有关数据应如何流动的更多信息。
另一个好读物:https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0