Tidak ada konsep baru, semuanya sudah tua.
Mengapa dva?
Setelah periode belajar mandiri atau pelatihan, setiap orang harus dapat memahami konsep redux dan menyadari bahwa kontrol aliran data ini dapat membuat aplikasi lebih terkontrol dan logika lebih jelas.
Tapi kemudian biasanya ada pertanyaan seperti itu: ada terlalu banyak konsep, dan reducer, saga, dan action semuanya terpisah (sub-file).
Masalah dengan ini adalah:
Dan beberapa lainnya:
Dan dva digunakan untuk memecahkan masalah ini.
dva adalah paket ringan berdasarkan arsitektur aplikasi yang ada (redux + react-router + redux-saga, dll.), tanpa memperkenalkan konsep baru, dan total kode kurang dari 100 baris. (Terinspirasi oleh elm dan choo.)
dva adalah framework, bukan library. Mirip dengan emberjs, dva akan dengan jelas memberi tahu Anda bagaimana setiap komponen harus ditulis, yang lebih dapat dikontrol untuk tim. Juga, dva merangkum semua dependensi lain kecuali react dan react-dom yang merupakan peerDependencies.
Dalam implementasi dva, cobalah untuk tidak membuat sintaks baru, tetapi gunakan sintaks dari pustaka dependensi itu sendiri, seperti definisi router atau sintaks JSX dari react-router (konfigurasi dinamis adalah pertimbangan kinerja, yang akan didukung nanti).
Inti dari itu adalah untuk menyediakan metode app.model
, yang digunakan untuk merangkum peredam, initialState, action, dan saga bersama-sama, seperti:
app.model({
namespace: 'products',
state: {
list: [],
loading: false,
},
subscriptions: [
function(dispatch) {
dispatch({type: 'products/query'});
},
],
effects: {
['products/query']: function*() {
yield call(delay(800));
yield put({
type: 'products/query/success',
payload: ['ant-tool', 'roof'],
});
},
},
reducers: {
['products/query'](state) {
return { ...state, loading: true, };
},
['products/query/success'](state, { payload }) {
return { ...state, loading: false, list: payload };
},
},
});
Sebelum dva, kita biasanya membuat sagas/products.js
, reducers/products.js
dan actions/products.js
dan kemudian beralih antara file-file ini.
Perkenalkan kunci model ini: (dengan asumsi Anda sudah terbiasa dengan arsitektur aplikasi redux, redux-saga)
Lihat contoh:
devtool
dukungan hot swapDukungan tingkat alat pengembangan?
Selain pengganti panas, yang belum diadaptasi, yang lain seperti redux-devtool, css livereload, dll semuanya kompatibel.
Apakah sudah tersedia untuk lingkungan build?
Bisa.
Apakah itu mencakup semua fitur arsitektur aplikasi redux + redux-saga sebelumnya?
Ya.
Kompatibilitas peramban?
IE8 tidak mendukungnya karena redux-saga digunakan. (Kami akan mempertimbangkan untuk mendukung thunks, janji, yang dapat diamati, dll. di lapisan efek secara diperpanjang nanti)
Menjadi hidup oleh redux hanyalah Injil. Itu terlalu sederhana dan elegan. Pujian yang luar biasa! ! !
btw, saya tidak sengaja melihat orang asing memposting ulang di Twitter hari ini, saya pikir itu ditulis oleh orang asing, tetapi saya tidak berharap itu menjadi teman sekelas Alipay, 👍
Menantikan perluasan efek
Apakah lingkungan produksi Alipay menggunakan arsitektur ini?
@besteric dva baru saja keluar, dan belum diterapkan, tetapi arsitektur aplikasi di belakangnya telah digunakan untuk sementara waktu.
Bisakah peredam ditulis seperti ini:
const reducer = (state, { type, payload }) => {
switch (type) {
case 'products/query':
return { ...state, loading: true, };
case 'products/query/success':
return { ...state, loading: false, list: payload };
default
return state;
}
}
app.model({
reducer
})
Ini memungkinkan untuk menerapkan beberapa metode tingkat tinggi ke peredam.
Pujian, saya menulis beberapa demo dan hanya ada satu masalah, modelnya hanya dapat digunakan
app.model(Model1);
app.model(Model2);
Apakah metode ini untuk menyelesaikan kombinasi, pada kenyataannya, saya pikir yang ideal adalah
app.model([Model1,Model2])
beberapa jenis
Terlalu merepotkan untuk melewatkan pengiriman antar komponen, pertimbangkan solusi berikut:
Jangan gunakan bindActionCreators
?
Apakah skenario khusus dari penggunaan lanjutan peredam @yesmeck hanya redo/undo
? Saya tidak ingin dva terlalu fleksibel, dan saya akan mempertimbangkan untuk menambahkannya melalui addon di masa mendatang.
Kami menggunakan banyak dalam proyek kami. Misalnya, kami akan mengekstrak bagian serupa dari beberapa reduksi menjadi metode tingkat tinggi untuk memodifikasi peredam asli, dan ada metode tingkat tinggi yang memungkinkan peredam untuk mengatur ulang status saat rute perubahan. , dan ini https://github.com/erikras/multireducer
@Tinker404 Saya merasa akan lebih jelas untuk mendeklarasikan model secara terpisah, dan akan lebih mudah untuk menambah dan menghapus. Saya akan menulis ini:
app.model(require('../models/a'));
app.model(require('../models/b'));
@JimmyLv secara pribadi memilih untuk tidak menggunakan actionCreator, tetapi hanya dispatch
.
@yesmeck ok, saya akan memikirkannya lagi.
Ada juga metode tingkat tinggi yang memungkinkan peredam untuk mengatur ulang status saat rute berubah
Saya merasa bahwa skenario ini lebih tepat dengan berlangganan perubahan perutean di subscriptions
, dan kemudian mengatur ulang status melalui tindakan. Atau apakah ada keuntungan menggunakan metode penambah peredam?
Saya merasa bahwa skenario ini lebih tepat dengan berlangganan perubahan perutean dalam langganan, dan kemudian mengatur ulang status melalui tindakan
Dalam hal ini, setiap peredam yang perlu direset perlu menulis logika reset. Jika kita menggunakan metode tingkat tinggi, kita hanya perlu melakukannya sekarang:
combineReducers({
products: composeReducers({ // composeReducers 的实现见下面
recycle(LOCATION_CHANGE, initialState), // recycle 用来在路由变化时重置状态
products
})
})
Skenario lain adalah logika yang sama yang saya bicarakan tentang mengekstraksi reduksi yang berbeda. Misalnya, ada daftar produk dan daftar pengguna, dan reduksinya seperti ini:
// reducers/products.js
const reducer = (state, { type, action}) => {
switch (type) {
case 'products/FETCH_SUCCESS':
return {
...state,
loading: false,
list: payload
}
default:
return state
}
}
// reducers/users.js
const reducer = (state, { type, payload}) => {
switch (type) {
case 'users/FETCH_SUCCESS':
return {
...state,
loading: false,
list: payload
}
default:
return state
}
}
Di sini kedua peredam hampir sama, jadi kami mengekstraknya dan menulis peredam daftar:
const list = (actionType) => {
return (state, { type, payload }) => {
switch (type) {
case actionType:
return {
...state,
loading: false,
list: payload
}
break;
default:
return state
}
}
}
Kemudian kami menerapkan composeReducers
untuk menggabungkan 3 reduksi ini:
function composeReducers(...reducers) {
return (state, action) => {
if (reducers.length === 0) {
return state
}
const last = reducers[reducers.length - 1]
const rest = reducers.slice(0, -1)
return rest.reduceRight((enhanced, reducer) => reducer(enhanced, action), last(state, action))
}
}
Dengan cara ini, peredam untuk daftar produk dan daftar pengguna menjadi ini:
// reducers/products.js
const reducer = (state, { type, payload}) => {
// 其他逻辑
}
export default composeReducer(reducer, list('products/FETCH_SUCCESS'))
// reducers/users.js
const reducer = (state, { type, payload}) => {
// 其他逻辑
}
export default composeReducer(reducer, list('users/FETCH_SUCCESS'))
list hanyalah sebuah contoh, pada kenyataannya, ada banyak reduksi dalam proyek yang memiliki logika yang sama.
@yesmeck 👍, peran penambah peredam telah diremehkan sebelumnya.
@sorrycc dapatkah Anda mengatakan mengapa? Disebut secara eksplisit dengan perbandingan dispatch
?
@Tinker404 Saya merasa akan lebih jelas untuk mendeklarasikan model secara terpisah, dan akan lebih mudah untuk menambah dan menghapus. Saya akan menulis ini:
app.model(memerlukan('../model/a'));
app.model(memerlukan('../models/b'));
Saya juga menyarankan metode yang dapat melewati beberapa model sekaligus. Proyek besar mungkin memiliki banyak model. Sekarang saya memerlukan (mengimpor) semuanya, dan kemudian memodelkan setiap model satu per satu, yang sangat tidak nyaman. Cara saya saat ini dari tulisan adalah:
// models是个文件夹,有很多model
import models from './models';
models.forEach((m)=>{
app.model(m);
});
// models.js
const context = require.context('./', false, /\.js$/);
const keys = context.keys().filter(item => item !== './index.js');
const models = [];
for (let i = 0; i < keys.length; i++) {
models.push(context(keys[i]));
}
export default models;
Ini sangat D.VA.
Saya menemukan penggunaan komponen bentuk antd di dasbor pengguna. Saya ingat bahwa itu tidak dapat digunakan untuk komponen murni. Apakah mungkin sekarang?
@codering Saya tidak ingat ada batasan, masalah dengan antd dapat ditanyakan di https://github.com/ant-design/ant-design/issues .
https://github.com/react-component/form/blob/master/README.md
Itu tertulis di CATATAN.
Halo, saya ingin menggunakan dva Anda. Saat ini, saya menggunakan struktur direktori yang dihasilkan oleh scaffolding React Webpack Redux. Saya telah mengubah kode dengan mengacu pada contoh dasbor pengguna dalam contoh Anda, tetapi tidak ada apa-apa setelah memulai. Dapatkah Anda membantu saya mencari tahu di mana itu? Ada yang tidak beres, alamat proyek saya: https://github.com/baiyulong/lenovo_parts
@baiyulong mengapa tidak melakukannya secara langsung berdasarkan struktur direktori dasbor pengguna?
@sorrycc Saya menggunakan struktur direktori dasbor pengguna sekarang. Apakah ada perlakuan atau penulisan khusus untuk perutean dva?
export default function({ history }) {
return (
<Router history={history}>
<IndexRoute component={HomePage} />
<Route path='/' component={HomePage}>
<Route path='/create' component={CreateOrder} />
</Route>
</Router>
)
}
Rute ini saya tulis, HomePage bisa, saya menulis tautan <Link to='/create'>Create</Link>
, saya tidak bisa masuk ke komponen CreateOrder setelah mengkliknya
Tidak ada cara khusus untuk menulis rute @baiyulong dva , silakan coba:
@nikogu terima kasih banyak, saya akan baik-baik saja setelah saya keluar dari sarangnya
Halo, dapatkah dva mendukung pemuatan model yang panas?
@kkkf1190 sedang mempertimbangkan ini dan akan mendukungnya.
👍
Hanya ingin mengucapkan terima kasih. . .
Saya selalu berpikir bahwa perancah vue-cli dari vuejs sangat bagus.Setelah membaca ini, pemikiran saya benar-benar berubah.
Bingkai yang sangat indah! Telah meneliti untuk sementara waktu. @sorrycc Saya ingin menanyakan dua pertanyaan kepada Yunda:
@freemember007
@sorrycc Apakah ada solusi untuk dukungan peredam tingkat tinggi sekarang? Proyek kami menggunakan banyak reduksi tingkat tinggi karena penggunaan kembali
Didukung oleh @ancheel , bisa global atau lokal, referensi kasus penggunaan: https://github.com/dvajs/dva/blob/master/test/reducers-test.js
Setelah keadaan model dimodifikasi, bagaimana memodifikasinya lagi, masalah ini selalu terjadi sekarang
antd.js:32924 Peringatan: setState(...): Tidak dapat memperbarui selama transisi status yang ada (seperti dalam render
atau konstruktor komponen lain).Metode render harus merupakan fungsi murni dari props dan state; konstruktor efek samping adalah anti-pola, tetapi dapat dipindahkan ke componentWillMount
.
Sangat menarik, coba gunakan di lingkungan produksi, semoga terus dioptimalkan dan ditingkatkan
nerf ini!
Kerja bagus。Terima kasih!!
@sorrycc Menantikan untuk mendukung rendering sisi server!
Didukung oleh @mountainmoon , lihat https://github.com/sorrycc/dva-boilerplate-isomorphic .
Gelombang roda datang :+1:
Halo, saya baru saja berhubungan dengan mempelajari dva ini. Setelah membaca kode selama beberapa hari, saya memiliki beberapa pertanyaan di hati saya. Saya ingin bertanya:
Saya melihat bahwa demo Anda semua adalah aplikasi satu halaman, tetapi semuanya adalah aplikasi multi-halaman dalam pengembangan. Saya ingin bertanya, jika perutean tidak digunakan dalam pengembangan aplikasi multi-halaman, bagaimana cara memuat komponen sebagai gantinya, mungkin saya bertanya kepada orang bodoh. Agak membingungkan, karena saya tidak menggunakan perutean, sehingga pendengar yang diatur dalam model tidak jelas di mana harus memicu:
history.listen( lokasi => {
if(location.pathname === '/pengguna') {
menugaskan({
ketik: 'querySuccess',
muatan:{}
})
}
})
PS: Saat memuat data dalam metode querySuccess dan menggunakan ekspor default connect(mapStateToProps)(Users); kesalahan juga dilaporkan:
connect.js:41 Uncaught TypeError: Tidak dapat memanggil kelas sebagai fungsi
Saya merasa seperti orang bodoh dalam sekejap, saya tidak tahu apakah saya dapat menyusahkan Anda untuk menjelaskannya kepada saya, terima kasih!
Mengapa dva? tolong bahasa inggris
Saya tidak terlalu suka cara menulis ini.
@codering Anda menyebutkan penggunaan komponen bentuk antd di dasbor pengguna. Saya ingat bahwa itu tidak dapat digunakan untuk komponen murni. Apakah mungkin sekarang?
Saya juga paling sering menemukannya.Jika itu adalah komponen fungsi murni, fungsi getFieldDecorator tidak dapat diperoleh melalui props.form.getFieldDecorator.Jika Anda menggunakan ekstensi untuk membuat komponen, Anda bisa mendapatkannya.
Saya tidak tahu apakah Tuhan punya solusi @sorrycc
Bisakah Anda meluncurkan halaman yang sama dalam bahasa Inggris? Kami tidak dapat memahami ini, dan mengapa kami membutuhkan dva.
Halo, jika ini adalah proyek besar, statusnya akan sangat besar, dan akan sangat rumit untuk diproses. Apakah harus dipecah menjadi beberapa model?
@yazhou-zyz Saya memiliki masalah yang sama dengan Anda:
Peringatan: setState(...): Tidak dapat memperbarui selama transisi status yang ada (seperti dalam render atau konstruktor komponen lain). Metode render harus merupakan fungsi murni dari props dan status; efek samping konstruktor adalah anti-pola, tetapi dapat dipindahkan ke componentWillMount.
Saya ingin bertanya bagaimana Anda menyelesaikannya?
Mempelajari
terus belajar
dva adalah nilai referensi yang bagus untuk proyek konstruksi.
kerja bagus~
Di mana saya dapat menemukan dokumen dalam bahasa Inggris ??? Menerjemahkan topik dengan mesin penerjemah bermasalah dan pemahamannya tidak cukup. Dengan bahasa Inggris, kalian bisa menjangkau dunia. Tetap bekerja dengan baik!! :roket:
dva tidak dicoba dalam versi React-native 0.47.X dan React16.0.0
@vecold selalu dapat menggunakannya, mengatakan bahwa kode undangan atau pesan kesalahan tidak dapat digunakan
Apakah ada kemungkinan kita bisa mendapatkan terjemahan bahasa Inggris dari dokumen?
Terima kasih!
Dalam kode bisnis, contoh seperti itu biasa terjadi. Pembaruan status lokal dapat memengaruhi seluruh isi. Banyak tempat yang tidak perlu dirender ulang juga dirender ulang, yang sangat mengurangi kinerja halaman. Bisakah fungsi ini ditambahkan untuk secara otomatis menganalisis status yang bergantung pada koneksi redux untuk mengurangi perhitungan dan rendering ulang mapStateToProps yang tidak perlu 👍
Baik sekali
tapi itu membangun semua halaman ketika saya berharap untuk membangun satu halaman
_terjemahan tidak resmi_
Reduxnya bagus. Tetapi ada terlalu banyak konsep, reduksi terpisah, kisah dan tindakan (dibagi menjadi file yang berbeda)
Ini adalah pembungkus ringan di atas kerangka kerja yang ada (redux + react-router + redux-saga ...). Tidak ada konsep baru yang terlibat. < 100 baris kode. (Terinspirasi oleh elm dan choo.)
Ini adalah kerangka kerja, bukan perpustakaan. Seperti Ember.js, ini membatasi cara Anda menulis setiap bagian. Ini lebih terkontrol untuk kerja tim. Dva merangkum semua dependensi kecuali react dan react-dom sebagai peerDependencies
Implementasinya memperkenalkan sintaks baru sesedikit mungkin. Ini menggunakan kembali dependensi. Untuk exp., definisi router persis sama dengan JSX react-router.
Fungsionalitas inti adalah app.model
. Ini merangkum peredam, initialState, action, saga sama sekali.
app.model({
namespace: 'products',
state: {
list: [],
loading: false,
},
subscriptions: [
function(dispatch) {
dispatch({type: 'products/query'});
},
],
effects: {
['products/query']: function*() {
yield call(delay(800));
yield put({
type: 'products/query/success',
payload: ['ant-tool', 'roof'],
});
},
},
reducers: {
['products/query'](state) {
return { ...state, loading: true, };
},
['products/query/success'](state, { payload }) {
return { ...state, loading: false, list: payload };
},
},
});
Kami biasa membuat sagas/products.js, reducers/products.js actions/products.js
dan beralih di antara mereka.
Inti:
key
dari reducer
dalam objek rootReducer
initialState
dari reducer
Lihat contoh
devtool
hot-reloadEffects
mendukung lebih banyak model saga
Dukungan alat pengembang?
Kompatibel dengan redux-devtool, css livereload. Perlu lebih banyak pekerjaan untuk hot-reload
Bagus untuk prod env?
Tentu
Termasuk semua fungsi redux + redux-saga?
Ya
Kompatibilitas browser?
Tidak ada IE8 karena redux-saga. (Nanti mungkin berlaku thunk, janji, dapat diamati sebagai ekstensi pada lapisan efek)
tolong mirip
['products/query']: function*() {}
['products/query'](state) {}
Apa sintaksnya? Bisakah array digunakan sebagai nama fungsi?
@clemTheDasher Nama fungsi dapat dihitung kunci ( BUKAN array) dalam JavaScript. Referensi lebih detail untuk definisi Metode |
var obj = {
property( parameters… ) {},
*generator( parameters… ) {},
async property( parameters… ) {},
async* generator( parameters… ) {},
// with computed keys:
[property]( parameters… ) {},
*[generator]( parameters… ) {},
async [property]( parameters… ) {},
// compare getter/setter syntax:
get property() {},
set property(value) {}
};
Laporan pendatang baru, datang ke sini dan terus bekerja keras untuk mempelajari pengetahuan front-end
@clemTheDasher Itu adalah properti yang dihitung.
Mengapa tautan https://github.com/dvajs/dva/tree/master/examples/count 404?
Mempelajari!
menghadap tuhan
Terima kasih Tuhan, terima kasih untuk open source
saya tidak diizinkan untuk belajar dari kalian!
Saya belajar, terima kasih telah memiliki kerangka kerja yang nyaman untuk kami gunakan
Tautan demo di github telah kedaluwarsa.
@sorrycc apakah dva mendukung rendering sisi server sekarang?
Bisakah peredam ditulis seperti ini:
const reducer = (state, { type, payload }) => { switch (type) { case 'products/query': return { ...state, loading: true, }; case 'products/query/success': return { ...state, loading: false, list: payload }; default return state; } } app.model({ reducer })
Ini memungkinkan untuk menerapkan beberapa metode tingkat tinggi ke peredam.
Gaya penulisan Redux ringkas, dan hanya satu baris yang diperlukan untuk mengubah status, tetapi tampaknya beberapa baris kode ditulis bersama melalui gula sintaksis. Tetapi saya masih perlu menggunakan ...state
untuk mengirimkan status yang tersisa ke perhentian berikutnya, jika tidak, statusnya tidak akan lengkap. Dengan kata lain, selama fase pengurangan, beberapa keadaan mungkin hilang jika ditulis dengan tidak benar.
Dalam beberapa hal, ide Vuex lebih mudah dibaca dan lebih alami. Tulis sesuatu seperti ini (tidak persis).
const mutation = {
['products/query'](state) {
state.loading = true
},
['products/query/success'](state, payload) {
state.loading = false
state.list = payload
}
}
Dari segi kode, saya hanya peduli status apa yang saya (secara serempak) ubah. Vuex juga harus membungkus lapisan di luar untuk pengiriman berikutnya. Mungkin beberapa pemeriksaan defensif (menebak) juga dilakukan sebelum pengiriman, atau kait ditanam.
Tanya saya jika halaman contoh situs web resmi dva tidak dapat keluar dan melaporkan kesalahan, apakah ini peningkatan?
tolong mirip
['products/query']: function*() {} ['products/query'](state) {}
Apa sintaksnya? Bisakah array digunakan sebagai nama fungsi?
ES6 memungkinkan literal untuk mendefinisikan objek, (ekspresi) sebagai nama properti objek, yaitu, menempatkan ekspresi dalam tanda kurung siku.
Seperti
obj = {
['xxname']: 'what ever you defined',
['xxyy'](args) {
....
}
}
Ada pertanyaan, 'produk/kueri' digunakan untuk memproses panggilan reduksi, dan dikaitkan dengan namespace melalui string. Nanti jika proyek menjadi lebih besar, seperti ratusan metode. Jika namspace saya harus diubah. Untuk mengubah seratus metode?
@yesmeck 👍, peran penambah peredam telah diremehkan sebelumnya.
Tidak tahu apakah ada dukungan di sini?
Komentar yang paling membantu
Menjadi hidup oleh redux hanyalah Injil. Itu terlalu sederhana dan elegan. Pujian yang luar biasa! ! !
btw, saya tidak sengaja melihat orang asing memposting ulang di Twitter hari ini, saya pikir itu ditulis oleh orang asing, tetapi saya tidak berharap itu menjadi teman sekelas Alipay, 👍