2015-12-04 20 views
6

Tôi có ứng dụng React tự động tải mô-đun, bao gồm chức năng giảm tốc của mô-đun và sau đó gọi trình thay thế của Redux, thay thế bộ giảm tốc. Rất tiếc, tôi gặp phải lỗi củaReplaceReducer gây lỗi khóa bất ngờ

Khóa không mong muốn "bookEntry" được tìm thấy trong đối số initialState được truyền cho createStore. Dự kiến ​​sẽ tìm thấy một trong các khóa giảm tốc đã biết: "bookList", "root". Các khóa không mong muốn sẽ bị bỏ qua.

nơi bookEntry một khóa trên bộ giảm tốc cũ hơn đang được thay thế. Và bắt đầu với mô-đun bookEntry và chuyển sang bookList gây ra lỗi nghịch đảo này

Khóa không mong muốn "bookList" được tìm thấy trong đối số initialState được truyền cho createStore. Dự kiến ​​sẽ tìm thấy một trong các khóa giảm tốc đã biết: "bookEntry", "root". Các khóa không mong muốn sẽ bị bỏ qua.

Mã dưới đây - không nhận xét rằng mã nhận xét thực tế sửa lỗi này, nhưng tôi đoán là không cần thiết.

Tôi có làm điều gì đó sai trái với Redux đang tạo mã này cần thiết không?

function getNewReducer(reducerObj){ 
    if (!reducerObj) return Redux.combineReducers({ root: rootReducer }); 

    //store.replaceReducer(function(){ 
    // return { 
    //  root: rootReducer() 
    // } 
    //}); 

    store.replaceReducer(Redux.combineReducers({ 
     [reducerObj.name]: reducerObj.reducer, 
     root: rootReducer 
    })); 
} 
+0

Có lý do cụ thể nào bạn muốn xóa bộ giảm tốc trước đó khi tải mã động không? Tôi không hiểu lắm. Nói chung bạn muốn các bộ giảm tốc cũ ở lại, không được tháo ra. –

+0

@DanAbramov - hm, không có lý do cụ thể.Tôi chỉ giả định mô-đun đi sẽ "dọn dẹp" sau chính nó. Có phải đó không phải là cách tôi nên làm điều đó trong thực tế? Tôi có nên tắt một công văn để xóa dữ liệu của nó, nhưng để lại bộ giảm tốc? –

+0

Mục đích của "dọn dẹp" là gì? Thông thường, bạn chỉ cần giữ dữ liệu xung quanh trong trường hợp người dùng quay lại trang này. –

Trả lời

9

Nói chung chúng tôi không đề nghị bạn để “dọn dẹp” dữ liệu khi thay đổi tuyến hoặc tải các module mới. Điều này làm cho ứng dụng trở nên ít có thể đoán trước được. Nếu chúng ta đang nói về hàng trăm nghìn hồ sơ, thì chắc chắn. Đây có phải là khối lượng dữ liệu bạn định tải không?

Nếu chỉ có một vài nghìn mục trên mỗi trang, sẽ không có lợi ích khi dỡ chúng và có những nhược điểm liên quan đến sự phức tạp mà bạn thêm vào ứng dụng. Vì vậy, hãy đảm bảo bạn đang giải quyết một vấn đề thực sự và không tối ưu hóa sớm.

Bây giờ, đến thông điệp cảnh báo. Séc được xác định bên trong combineReducers(). Nó có nghĩa là các khóa trạng thái không mong muốn sẽ bị loại bỏ. Sau khi bạn xóa trình gỡ lỗi bookEntry được quản lý state.bookEntry, phần đó của tiểu bang không còn được công nhận bởi trình giảm gốc mới và combineReducers() đã ghi lại cảnh báo rằng nó sẽ bị loại bỏ. Lưu ý rằng đây là cảnh báo và không phải là lỗi. Mã của bạn chỉ chạy tốt. Chúng tôi sử dụng console.error() để cảnh báo nổi bật, nhưng nó không thực sự ném, vì vậy bạn có thể bỏ qua nó một cách an toàn.

Chúng tôi thực sự không muốn đặt cấu hình cảnh báo vì bạn thực chất là xóa xóa một phần của trạng thái đơn đăng ký. Thông thường mọi người làm điều này do nhầm lẫn, và không cố ý. Vì vậy, chúng tôi muốn cảnh báo về điều đó. Nếu bạn muốn nhận được xung quanh cảnh báo, đặt cược tốt nhất của bạn là viết bộ giảm gốc (hiện được tạo bởi combineReducers()) bằng tay. Nó sẽ trông như sau:

// I renamed what you called "root" reducer 
// to "main" reducer because the root reducer 
// is the combined one. 
let mainReducer = (state, action) => ... 

// This is like your own combineReducers() with custom behavior 
function getRootReducer(dynamicReducer) { 
    // Creates a reducer from the main and a dynamic reducer 
    return function (state, action) { 
    // Calculate main state 
    let nextState = { 
     main: mainReducer(state.main, action) 
    }; 

    // If specified, calculate dynamic reducer state 
    if (dynamicReducer) { 
     nextState[dynamicReducer.name] = dynamicReducer.reducer(
     nextState[dynamicReducer.name], 
     action 
    ); 
    } 

    return nextState; 
    }; 
} 

// Create the store without a dynamic reducer 
export function createStoreWithoutDynamicReducer() { 
    return Redux.createStore(getRootReducer()); 
} 

// Later call this to replace the dynamic reducer on a store instance 
export function setDynamicReducer(store, dynamicReducer) { 
    store.replaceReducer(getRootReducer(dynamicReducer)); 
} 

Tuy nhiên, mẫu chúng tôi đề xuất là keep the old reducers around.

+0

Cảm ơn Dan - theo luật tôi phải đợi thêm 17 giờ nữa giải thưởng tiền thưởng :) Cảm ơn bạn rất nhiều vì thông tin. Những ngày của các tiện ích chiến đấu của tôi dài hơn; Tôi sẽ sẵn sàng để lại các bộ giảm tốc cũ, và chỉ đơn giản là xóa dữ liệu quá mức nếu thực sự cần thiết. Bất kỳ cơ hội nào bạn có thể thấy cách để nhận một số thông tin này vào tài liệu? Điều này là khá nhiều * chỉ * một phần của Redux, nơi các tài liệu được một chút hạn chế. –

+0

@Adam Tôi có nghĩa là không có thời gian để đóng góp cho các tài liệu ngay bây giờ. Có một nhu cầu cho một công thức "nạp mã động" toàn diện nhưng ai đó cần sở hữu nó, và tôi không thể. –

+0

không phải lo lắng gì cả. Bạn đã làm khá nhiều cho cộng đồng dev. Bạn có chấp nhận một PR với một số tài liệu cập nhật trên replaceReducer, sau khi tôi dành một chút thời gian với nó để quấn đầu của tôi xung quanh những thứ tốt hơn một chút? –

Các vấn đề liên quan