Pada dasarnya, alat peraga dan keadaan adalah dua cara komponen dapat mengetahui apa dan bagaimana membuatnya. Bagian mana dari status aplikasi milik negara dan yang ke beberapa toko tingkat atas, lebih terkait dengan desain aplikasi Anda, daripada bagaimana React bekerja. Cara paling sederhana untuk memutuskan, IMO, adalah dengan berpikir, apakah data tertentu ini berguna untuk aplikasi secara keseluruhan, atau itu adalah informasi lokal. Juga, penting untuk tidak menggandakan status, jadi jika sebagian data dapat dihitung dari alat peraga - itu harus dihitung dari alat peraga.
Sebagai contoh, katakanlah Anda memiliki beberapa kontrol dropdown (yang membungkus standar HTML pilih untuk styling kustom), yang dapat a) memilih beberapa nilai dari daftar, dan b) dibuka atau ditutup (yaitu, daftar opsi ditampilkan atau disembunyikan). Sekarang, katakanlah aplikasi Anda menampilkan daftar barang dari beberapa jenis dan filter kontrol dropdown Anda untuk entri daftar. Kemudian, akan lebih baik untuk melewatkan nilai filter aktif sebagai penyangga, dan tetap membuka / menutup status lokal. Selain itu, untuk membuatnya berfungsi, Anda akan meneruskan penangan onChange dari komponen induk, yang akan dipanggil di dalam elemen dropdown dan mengirim informasi yang diperbarui (filter baru yang dipilih) ke toko segera. Di sisi lain, keadaan buka / tutup dapat disimpan di dalam komponen dropdown, karena sisa aplikasi tidak terlalu peduli jika kontrol dibuka, sampai pengguna benar-benar mengubah nilainya.
Kode berikut ini tidak sepenuhnya berfungsi, perlu css dan menangani dropdown klik / blur / ubah acara, tapi saya ingin menyimpan contoh minimal. Semoga ini membantu untuk memahami perbedaannya.
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')
);