React Native - Lợi ích của việc sử dụng StyleSheet so với một đối tượng thuần túy là gì?


105

Chính xác thì lợi ích của việc sử dụng StyleSheet.create()so với một đối tượng thuần túy là gì?

const styles = StyleSheet.create({
  container: {
    flex: 1
  }
}

Vs.

const styles = {
  container: {
    flex: 1
  }
}

Tôi nhận được hỗ trợ intellisense VSCode cho các thuộc tính. Đó là lợi ích.
helloworld

Câu trả lời:


42

Trích dẫn trực tiếp từ phần bình luận của StyleSheet.js của React native

Chất lượng mã:

  • Bằng cách di chuyển các kiểu ra khỏi chức năng kết xuất, bạn đang làm cho mã dễ hiểu hơn.

  • Đặt tên cho các kiểu là một cách tốt để thêm ý nghĩa cho các thành phần cấp thấp trong hàm kết xuất.

Hiệu suất:

  • Tạo biểu định kiểu từ một đối tượng kiểu giúp bạn có thể tham chiếu đến nó theo ID thay vì tạo một đối tượng kiểu mới mọi lúc.

  • Nó cũng cho phép gửi style chỉ một lần qua cầu. Tất cả các lần sử dụng tiếp theo sẽ tham chiếu đến một id (chưa được triển khai).

Ngoài ra StyleSheet cũng xác nhận nội dung biểu định kiểu của bạn. Vì vậy, bất kỳ lỗi nào của thuộc tính kiểu không chính xác được hiển thị tại thời điểm biên dịch thay vì trong thời gian chạy khi StyleSheet thực sự được triển khai.


46
Ba gạch đầu dòng đầu tiên không liên quan đến kỹ thuật khai báo đối tượng kiểu dáng của OP là một const bên ngoài hàm kết xuất.
Owen Masback

12
Khi tôi đọc lời giải thích, tôi vẫn không thấy làm thế nào StyleSheet.create({styles...})là tốt hơn / nhanh hơn {styles...}. Mã cũng rõ ràng và bạn cũng đang sử dụng đặt tên thay vì nội tuyến. Bất cứ ai có thể làm sáng tỏ về nó?
freeall

9
StyleSheetcung cấp xác nhận khi biên dịch
Jeevan Takhar

10
Bị phản đối. Đừng đưa thông tin không liên quan ("bằng cách di chuyển các kiểu ra khỏi chức năng kết xuất", v.v.) trong câu trả lời của bạn.
Roymunson

5
Downvoted, câu hỏi của OP là sự khác biệt giữa StyleSheet.createvà một đối tượng đơn giản, không inline vs một const bên ngoài lớp
quirimmo

56

Không có lợi ích gì. Giai đoạn = Stage.

Lầm tưởng 1: StyleSheethiệu quả hơn

Hoàn toàn không có sự khác biệt về hiệu suất giữa StyleSheetvà một đối tượng được khai báo bên ngoài render(sẽ khác nếu bạn luôn tạo một đối tượng mới bên trong render). Sự khác biệt về hiệu suất là một huyền thoại.

Nguồn gốc của câu chuyện hoang đường có thể là do nhóm React Native đã cố gắng làm điều này, nhưng họ đã không thành công. Không ở đâu trong tài liệu chính thức, bạn sẽ tìm thấy bất cứ điều gì về hiệu suất: https://facebook.github.io/react-native/docs/stylesheet.html , trong khi mã nguồn trạng thái "chưa được triển khai": https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Lầm tưởng 2: StyleSheetXác thực đối tượng kiểu tại thời điểm biên dịch

Đây không phải là sự thật. JavaScript thuần túy không thể xác thực các đối tượng tại thời điểm biên dịch.

Hai điều:

  • Nó xác thực trong thời gian chạy, nhưng cũng vậy khi bạn chuyển đối tượng kiểu cho một thành phần. Không khác nhau.
  • Nó không xác thực tại thời điểm biên dịch nếu bạn đang sử dụng Flow hoặc TypeScript , nhưng điều này cũng xảy ra khi bạn chuyển đối tượng làm định dạng cho một thành phần hoặc nếu bạn gõ đúng đối tượng như bên dưới. Cũng không có gì khác biệt.
const containerStyle: ViewStyle = {
   ...
}

3
Thật. Có lẽ sự nhầm lẫn đến từ phiên bản tài liệu trước đó của họ ngụ ý rằng cuối cùng họ đã chuyển sang các kiểu tham chiếu bằng id. Điều đó không được đề cập trong 0,59 tài liệu.
ermzeit

1
THX để làm sáng tỏ. Nhưng câu hỏi còn bỏ ngỏ - Để làm gì?
Vasiliy Vanchuk


Cảm ơn bạn vì câu trả lời này. Nó xứng đáng nhận được nhiều
phiếu bầu

3
Thử nghiệm của tôi chỉ ra rằng nó xác thực trong thời gian chạy mà không cần phải chuyển đến một thành phần, ví dụ: StyleSheet.create( {x:{flex: "1"}} )sẽ không thành công trong thời gian chạy, cũng như một bản định kiểu sẽ kiểm tra điều này tại thời điểm biên dịch.
Glenn Lawrence

24

Câu trả lời được chấp nhận không phải là câu trả lời cho câu hỏi OP.

Câu hỏi không phải là sự khác biệt giữa kiểu nội tuyến và kiểu constbên ngoài lớp, mà là tại sao chúng ta nên sử dụng StyleSheet.createthay vì một đối tượng thuần túy.

Sau một chút nghiên cứu những gì tôi tìm thấy là sau (vui lòng cập nhật nếu bạn có bất kỳ thông tin nào). Các advatang của StyleSheet.createphải như sau:

  1. Nó xác thực các kiểu
  2. Các chuẩn chỉnh chu tốt hơn vì nó tạo ánh xạ các kiểu tới một ID và sau đó nó tham chiếu bên trong với ID này, thay vì tạo mỗi lần một đối tượng mới. Vì vậy, ngay cả quá trình cập nhật thiết bị cũng nhanh hơn vì bạn không phải gửi tất cả các đối tượng mới mọi lúc.

11
Đây là những huyền thoại. Kiểm tra câu trả lời của tôi.
Nikola Mihajlović Ngày

Nếu tôi xác định đối tượng kiểu bên ngoài lớp (hoặc thậm chí là thuộc tính lớp) thì nó sẽ được tạo một lần (hoặc một lần cho mỗi trường hợp). Các đối tượng tương tự được tạo lại chỉ là các chức năng bên trong có liên quan.
Thứ Bảy,

Đúng cho const, nhưng nope thuộc tính lớp. Thuộc tính lớp tĩnh yep.
quirimmo

5

Trước đây, người ta coi rằng sử dụng StyleSheet hiệu quả hơn và được nhóm RN khuyến nghị vì lý do này cho đến phiên bản 0.57, nhưng hiện nay nó không còn được khuyến khích như đã chỉ ra một cách chính xác trong một câu trả lời khác cho câu hỏi này.

Các tài liệu RN nay khuyến cáo StyleSheet vì những lý do sau đây, mặc dù tôi nghĩ rằng những lý do này sẽ được áp dụng như nhau đối với đối tượng đơn giản được tạo ra bên ngoài của hàm render:

  • Bằng cách di chuyển các kiểu ra khỏi chức năng kết xuất, bạn đang làm cho mã dễ hiểu hơn.
  • Đặt tên cho các kiểu là một cách tốt để thêm ý nghĩa cho các thành phần cấp thấp trong hàm kết xuất.

Vì vậy, những gì tôi nghĩ được những lợi ích có thể của việc sử dụng StyleSheet đối với đối tượng đồng bằng?

1) Mặc dù tuyên bố ngược lại thử nghiệm của tôi trên RN v0.59.10 chỉ ra rằng bạn làm được một số xác nhận khi gọi StyleSheet.create()và nguyên cảo (và có lẽ chảy) cũng sẽ báo cáo lỗi tại thời gian biên dịch. Ngay cả khi không kiểm tra thời gian biên dịch, tôi nghĩ vẫn có lợi khi thực hiện xác thực thời gian chạy của các kiểu trước khi chúng được sử dụng để hiển thị, đặc biệt khi các thành phần sử dụng các kiểu đó có thể được hiển thị có điều kiện. Điều này sẽ cho phép các lỗi như vậy được phát hiện mà không cần phải kiểm tra tất cả các kịch bản kết xuất.

2) Vì StyleSheet được nhóm RN đề xuất, họ vẫn có thể hy vọng sử dụng StyleSheet để cải thiện hiệu suất trong tương lai và họ cũng có thể có những cải tiến có thể có khác, ví dụ:

3) Việc StyleSheet.create()xác nhận thời gian chạy hiện tại rất hữu ích, nhưng hơi hạn chế. Nó dường như bị hạn chế đối với việc kiểm tra kiểu mà bạn sẽ nhận được với luồng hoặc bảng chữ, vì vậy sẽ chọn say flex: "1"hoặc borderStyle: "rubbish", nhưng không phải width: "rubbish"vì đó có thể là một chuỗi phần trăm. Có thể nhóm RN có thể cải thiện việc xác thực như vậy trong tương lai bằng cách kiểm tra những thứ như chuỗi tỷ lệ phần trăm hoặc giới hạn phạm vi hoặc bạn có thể sử dụng StyleSheet.create()hàm của riêng mình để thực hiện xác thực rộng rãi hơn.

4) Bằng cách sử dụng StyleSheet, bạn có thể dễ dàng chuyển đổi sang các lựa chọn thay thế / tiện ích mở rộng của bên thứ ba như biểu định kiểu react-native- extension - cung cấp nhiều hơn.


1

Việc tạo kiểu của bạn thông qua StyleSheet.createsẽ chỉ vượt qua xác thực khi biến toàn cục __DEV__được đặt thành true (hoặc trong khi chạy bên trong trình giả lập Android hoặc IOS, hãy xem các biến React Native DEV và PROD )

nguồn của hàm khá đơn giản:

create < +S: ____Styles_Internal > (obj: S): $ReadOnly < S > {
  // TODO: This should return S as the return type. But first,
  // we need to codemod all the callsites that are typing this
  // return value as a number (even though it was opaque).
  if (__DEV__) {
    for (const key in obj) {
      StyleSheetValidation.validateStyle(key, obj);
      if (obj[key]) {
        Object.freeze(obj[key]);
      }
    }
  }
  return obj;
}

Tôi khuyên bạn nên sử dụng nó vì nó thực hiện xác thực thời gian chạy trong quá trình phát triển, đồng thời nó cũng đóng băng đối tượng.


0

Tôi không tìm thấy bất kỳ sự khác biệt nào trong StyleSheetđối tượng giữa và đối tượng thuần túy, ngoại trừ việc nhập xác thực trong TypeScript.

Ví dụ: điều này (lưu ý sự khác biệt về cách đánh máy):

import { View, Text, Image, StyleSheet } from 'react-native';
import logo from './logo.svg';

export default class App extends Component {
  render() {
    return (
      <View style={styles.someViewStyle}>
        <Text style={styles.someTextStyle}>Text Here</Text>
        <Image style={styles.someImageStyle} source={logo} />
      </View>
    );
  }
}

const styles: StyleSheet.create({
  someViewStyle: {
    backgroundColor: '#FFF',
    padding: 10,
  },
  someTextStyle: {
    fontSize: 24,
    fontWeight: '600',
  },
  someImageStyle: {
    height: 50,
    width: 100,
  },
});

tương đương với điều này:

import { View, Text, Image, ViewStyle, TextStyle, ImageStyle } from 'react-native';
import logo from './logo.svg';

export default class App extends Component {
  render() {
    return (
      <View style={styles.someViewStyle}>
        <Text style={styles.someTextStyle}>Text Here</Text>
        <Image style={styles.someImageStyle} source={logo} />
      </View>
    );
  }
}

const styles: {
  someViewStyle: ViewStyle;
  someTextStyle: TextStyle;
  someImageStyle: ImageStyle;
} = {
  someViewStyle: {
    backgroundColor: '#FFF',
    padding: 10,
  },
  someTextStyle: {
    fontSize: 24,
    fontWeight: '600',
  },
  someImageStyle: {
    height: 50,
    width: 100,
  },
};
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.