2016-07-03 18 views
5

Tôi đang sử dụng React với SSR FlowRouter.Phản hồi SSR - xử lý window.height/width

Vì dòng này:

var height = (Meteor.isClient ? window.innerHeight : 0); 
<div style={{top: height+'px' }}> 

tôi nhận được một cảnh báo như vậy:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server.

Tôi biết Thats vì sự khác biệt giữa khách hàng và mã máy chủ (Tôi không có quyền truy cập vào cửa sổ trên máy chủ của tôi).

Có cách nào để tránh cảnh báo này không?

+1

Cảm ơn bạn đã đăng, bạn có hiểu điều này không? – Coherent

Trả lời

2

Cảnh báo bạn đang gặp phải là do lỗi kiểm tra giữa html được hiển thị ban đầu trên máy chủ và máy khách. Như bạn đã chỉ ra một cách chính xác, điều này là bởi vì, bạn không có đối tượng window trên máy chủ và do đó, không thể tính toán window.innerHeight. Điều này làm cho html được hiển thị khác biệt trong thuộc tính style của div và gây ra cảnh báo.

Sự chỉnh sửa có sẽ được di chuyển biến height đến state của các thành phần và đặt nó vào một trạng thái ban đầu là 0. Sau đó thực hiện việc kiểm tra

this.setState({height: (Meteor.isClient ? window.innerHeight : 0)}); 

trong componentWillMount và thiết lập chiều cao chính xác ở đây. Bằng cách này, việc render ban đầu của cả client và server sẽ giống nhau. Tuy nhiên, vì componentDidMount chỉ được gọi trên máy khách, nó sẽ hiển thị lại thành phần với đúng height từ số window khi thay đổi state.

Từ docs

Nếu bạn cố ý cần phải làm một cái gì đó khác nhau trên máy chủ và máy khách, bạn có thể làm một rendering hai-pass. Các thành phần hiển thị điều gì đó khác trên máy khách có thể đọc biến trạng thái như this.state.isClient, mà bạn có thể đặt thành true trong componentDidMount(). Bằng cách này, đường dẫn render ban đầu sẽ hiển thị cùng nội dung với máy chủ, tránh sự không khớp, nhưng một đường chuyền bổ sung sẽ xảy ra đồng bộ ngay sau khi hydrat hóa. Lưu ý rằng cách tiếp cận này sẽ làm cho các thành phần của bạn chậm hơn vì chúng phải hiển thị hai lần, vì vậy hãy sử dụng nó một cách thận trọng.

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