โดยพื้นฐานแล้วอุปกรณ์ประกอบฉากและสถานะเป็นสองวิธีที่องค์ประกอบสามารถรู้ได้ว่าจะแสดงผลอย่างไรและอย่างไร ส่วนใดของสถานะแอปพลิเคชันที่เป็นของรัฐและในร้านค้าระดับบนสุดเกี่ยวข้องกับการออกแบบแอปของคุณมากกว่าการทำงานของ React วิธีที่ง่ายที่สุดในการตัดสินใจ IMO คือการคิดว่าข้อมูลส่วนนี้มีประโยชน์สำหรับแอปพลิเคชั่นโดยรวมหรือเป็นข้อมูลท้องถิ่น นอกจากนี้สิ่งสำคัญคือต้องไม่ทำซ้ำสถานะดังนั้นหากข้อมูลบางอย่างสามารถคำนวณได้จากอุปกรณ์ประกอบฉาก - ควรคำนวณจากอุปกรณ์ประกอบฉาก
ตัวอย่างเช่นสมมติว่าคุณมีตัวควบคุมแบบเลื่อนลงบางส่วน (ซึ่งล้อมรอบเลือก HTML แบบมาตรฐานสำหรับการกำหนดสไตล์เอง) ซึ่งสามารถก) เลือกค่าบางอย่างจากรายการและ b) เปิดหรือปิด (เช่นรายการตัวเลือกที่แสดงหรือซ่อน) ตอนนี้สมมติว่าแอปของคุณแสดงรายการของการเรียงลำดับบางส่วนและตัวกรองการควบคุมแบบเลื่อนลงของคุณสำหรับรายการ จากนั้นจะเป็นการดีที่สุดที่จะส่งค่าตัวกรองที่ใช้งานเป็นเสาและรักษาสถานะเปิด / ปิดในท้องถิ่น นอกจากนี้เพื่อให้สามารถใช้งานได้คุณจะต้องส่งผ่านตัวจัดการ onChange จากองค์ประกอบหลักซึ่งจะเรียกว่าองค์ประกอบภายในรายการแบบเลื่อนลงและส่งข้อมูลที่อัปเดต ในทางตรงกันข้ามสถานะเปิด / ปิดสามารถเก็บไว้ในองค์ประกอบแบบเลื่อนลงได้เนื่องจากส่วนที่เหลือของแอปพลิเคชันไม่สนใจจริงๆว่าจะเปิดการควบคุมหรือไม่จนกว่าผู้ใช้จะเปลี่ยนค่า
รหัสต่อไปนี้ใช้งานไม่ได้ต้องใช้ css และจัดการเหตุการณ์คลิก / เบลอ / เปลี่ยนแบบเลื่อนลง แต่ฉันต้องการให้ตัวอย่างน้อยที่สุด หวังว่ามันจะช่วยให้เข้าใจความแตกต่าง
const _store = {
items: [
{ id: 1, label: 'One' },
{ id: 2, label: 'Two' },
{ id: 3, label: 'Three', new: true },
{ id: 4, label: 'Four', new: true },
{ id: 5, label: 'Five', important: true },
{ id: 6, label: 'Six' },
{ id: 7, label: 'Seven', important: true },
],
activeFilter: 'important',
possibleFilters: [
{ key: 'all', label: 'All' },
{ key: 'new', label: 'New' },
{ key: 'important', label: 'Important' }
]
}
function getFilteredItems(items, filter) {
switch (filter) {
case 'all':
return items;
case 'new':
return items.filter(function(item) { return Boolean(item.new); });
case 'important':
return items.filter(function(item) { return Boolean(item.important); });
default:
return items;
}
}
const App = React.createClass({
render: function() {
return (
<div>
My list:
<ItemList items={this.props.listItems} />
<div>
<Dropdown
onFilterChange={function(e) {
_store.activeFilter = e.currentTarget.value;
console.log(_store); // in real life, some action would be dispatched here
}}
filterOptions={this.props.filterOptions}
value={this.props.activeFilter}
/>
</div>
</div>
);
}
});
const ItemList = React.createClass({
render: function() {
return (
<div>
{this.props.items.map(function(item) {
return <div key={item.id}>{item.id}: {item.label}</div>;
})}
</div>
);
}
});
const Dropdown = React.createClass({
getInitialState: function() {
return {
isOpen: false
};
},
render: function() {
return (
<div>
<select
className="hidden-select"
onChange={this.props.onFilterChange}
value={this.props.value}>
{this.props.filterOptions.map(function(option) {
return <option value={option.key} key={option.key}>{option.label}</option>
})}
</select>
<div className={'custom-select' + (this.state.isOpen ? ' open' : '')} onClick={this.onClick}>
<div className="selected-value">{this.props.activeFilter}</div>
{this.props.filterOptions.map(function(option) {
return <div data-value={option.key} key={option.key}>{option.label}</div>
})}
</div>
</div>
);
},
onClick: function(e) {
this.setState({
isOpen: !this.state.isOpen
});
}
});
ReactDOM.render(
<App
listItems={getFilteredItems(_store.items, _store.activeFilter)}
filterOptions={_store.possibleFilters}
activeFilter={_store.activeFilter}
/>,
document.getElementById('root')
);