2015-02-15 30 views
11

Khi sử dụng React để hiển thị các thành phần trên máy chủ, tôi nhận thấy rằng các thuộc tính data-reactid có hiệu quả ngẫu nhiên. Tôi hiểu điều đó được mong đợi. (https://groups.google.com/forum/#!topic/reactjs/ewTN-WOP1w8)Phản ứng ổn định để hiển thị phía máy chủ

Tuy nhiên có một chút ngạc nhiên khi khung chức năng khác này giới thiệu tính không xác định như vậy trong đầu ra khung nhìn. Điều đó có nghĩa là các bản render liên tiếp của một khung nhìn với trạng thái giống hệt nhau sẽ tạo ra các HTML khác nhau, ngăn chặn, ví dụ, công cụ xem từ trả về một '304 Không được sửa đổi' hoặc tạo ra một ETag đáng tin cậy. (Tôi đánh giá cao bộ nhớ đệm như vậy có thể được xử lý ở lớp cơ sở hạ tầng cao hơn.)

Có cách nào để tạo hạt nhận dạng sao cho các chất phản ứng là xác định? Hoặc là lý do đó là một ý tưởng tồi được giải thích ở một nơi khác?

Trả lời

2

Trong bình luận cuối cùng về các Google Group thread Ben Alpert nói:

Đối với máy chủ rendering, điều quan trọng là các thành phần render khác nhau không có ID va chạm (ngay cả khi họ đang render trên các máy chủ khác nhau, ví dụ) vì vậy chúng tôi chọn ngẫu nhiên.

+1

Khác với việc nói "điều quan trọng", không rõ tại sao lại như vậy. –

+1

Tôi đọc nhận xét của anh ấy nói lý do React sử dụng các ID ngẫu nhiên là vì các thành phần không thể có ID xung đột, thậm chí trên các máy chủ khác nhau. Có một số cuộc nói chuyện về việc thay đổi [làm thế nào các ID ngẫu nhiên được tạo ra trên Github] (https://github.com/facebook/react/issues/2584) và bạn có thể làm theo hướng dẫn của họ để tạo ID của riêng bạn nếu muốn. –

1

Ngoài ra thời gian gần đây nghĩ về nó (chỉ mới bắt đầu sử dụng reactjs),

giải pháp có thể là khá đơn giản - không có yêu cầu cho ETag được tạo ra từ html thực ... - nó có thể được tạo ra từ hiển thị dữ liệu.

Vì vậy, bạn có thể tạo ra nó từ dom ảo - chỉ cần sử dụng React.renderComponentToStaticMarkup(…) và tạo ETag từ nó ...

Hoặc bạn có thể loại bỏ tất cả của reactid từ html rendered với regexp trước khi băm nó (có thể nhanh hơn sau đó riêng render). ..

Trong trường hợp nếu bạn đang sử dụng rõ ràng, đây sẽ là một cái gì đó như:

var virtualDom = React.createFactory(Handler)({}); 
var html = React.renderToString(virtualDom); 

var etag = app.get('etag fn'); 
if (etag) { 
    etag = etag(React.renderComponentToStaticMarkup(virtualDom), 'utf8'); 
    etag && res.set('ETag', etag); 
} 

res.render(...); 
0

này được bugging tôi quá, vì vậy tôi đã làm một số đào để xem những gì sẽ xảy ra nếu tôi làm gốc reactid xác định .

Có thể ghi đè lên điều này trong React 0.14.x nếu bạn sẵn sàng đưa ra bản hack sau. Trong file server-side của bạn, nơi bạn gọi ReactDOM.renderToString, đặt này ở đầu trang:

// Override the ServerReactRootIndex.createReactRootIndex function 
var ServerReactRootIndex = require('react/lib/ServerReactRootIndex'); 
ServerReactRootIndex.createReactRootIndex = function(){ 
    return "x"; // Results in an attribute like data-reactid=".x" 
}; 

// Use React as usual 
// NB: require('react') must come AFTER overriding ServerReactRootIndex.createReactRootIndex 
var React = require('react'); 

Đây không phải là một phần của Phản ứng API, vì vậy đây có thể phá vỡ trong tương lai gần. Tuy nhiên, điều này làm việc cho bây giờ nếu bạn hoàn toàn cần nó. Nó cũng làm cho thuộc tính data-react-checksum ổn định cho cùng một DOM được trả về.

Nếu bạn có nhiều thành phần gốc React trong một trang, chúng phải có các id gốc khác nhau, vì vậy bạn sẽ cần phải sửa đổi hàm này để tính toán điều này.

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