React Native - ประโยชน์ของการใช้ StyleSheet กับวัตถุธรรมดาคืออะไร?


109

ประโยชน์ของการใช้StyleSheet.create()vs วัตถุธรรมดาคืออะไร?

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

เทียบกับ

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

ฉันได้รับการสนับสนุน VSCode intellisense สำหรับคุณสมบัติ นั่นคือประโยชน์
helloworld

คำตอบ:


43

อ้างอิงโดยตรงจากส่วนความคิดเห็นของStyleSheet.jsของ React native

คุณภาพรหัส:

  • การย้ายสไตล์ออกจากฟังก์ชันการแสดงผลจะทำให้คุณเข้าใจโค้ดได้ง่ายขึ้น

  • การตั้งชื่อสไตล์เป็นวิธีที่ดีในการเพิ่มความหมายให้กับส่วนประกอบระดับต่ำในฟังก์ชันการแสดงผล

ประสิทธิภาพ:

  • การสร้างสไตล์ชีตจากสไตล์อ็อบเจกต์ทำให้สามารถอ้างถึงด้วย ID แทนที่จะสร้างสไตล์อ็อบเจกต์ใหม่ทุกครั้ง

  • นอกจากนี้ยังอนุญาตให้ส่งรูปแบบเพียงครั้งเดียวผ่านสะพาน การใช้งานที่ตามมาทั้งหมดจะอ้างถึง id (ยังไม่ได้ใช้งาน)

นอกจากนี้ StyleSheet ยังตรวจสอบเนื้อหาสไตล์ชีตของคุณด้วย ดังนั้นข้อผิดพลาดใด ๆ ของคุณสมบัติสไตล์ที่ไม่ถูกต้องจะแสดงในขณะคอมไพล์แทนที่จะเป็นรันไทม์เมื่อใช้ StyleSheet จริง


47
สัญลักษณ์แสดงหัวข้อย่อยสามจุดแรกไม่เกี่ยวข้องกับเทคนิคของ OP ในการประกาศ style object เป็น const นอกฟังก์ชันการแสดงผล
Owen Masback

12
เมื่อฉันอ่านคำอธิบายฉันยังไม่เห็นว่าStyleSheet.create({styles...})ดีกว่า / เร็วกว่า{styles...}อย่างไร รหัสนั้นสะอาดพอ ๆ กันและคุณยังใช้การตั้งชื่อแทนการฝังใน ใครช่วยส่องให้หน่อยได้มั้ยคะ?
ฟรีตลอด

9
StyleSheetให้การตรวจสอบความถูกต้องในการรวบรวม
Jeevan Takhar

11
โหวตลดลง อย่าใส่ข้อมูลที่ไม่เกี่ยวข้อง ("โดยการย้ายสไตล์ออกจากฟังก์ชันการแสดงผล" ฯลฯ ) ในคำตอบของคุณ
Roymunson

6
โหวตลงคำถามของ OP คือความแตกต่างระหว่างStyleSheet.createและวัตถุธรรมดาไม่ใช่แบบอินไลน์กับ const นอกคลาส
quirimmo

60

ไม่มีประโยชน์อะไรเลย ระยะเวลา

ความเชื่อที่ 1: StyleSheetมีประสิทธิภาพมากขึ้น

ไม่มีความแตกต่างด้านประสิทธิภาพอย่างแน่นอนระหว่างStyleSheetและวัตถุที่ประกาศภายนอกrender(มันจะแตกต่างกันถ้าคุณสร้างวัตถุใหม่ภายในrenderทุกครั้ง) ความแตกต่างของประสิทธิภาพเป็นตำนาน

ที่มาของตำนานน่าจะเป็นเพราะทีม React Native พยายามทำสิ่งนี้ แต่ไม่ประสบความสำเร็จ ไม่มีที่ไหนในเอกสารอย่างเป็นทางการคุณจะพบทุกอย่างเกี่ยวกับประสิทธิภาพ: https://facebook.github.io/react-native/docs/stylesheet.htmlในขณะที่ซอร์สโค้ดระบุว่า "ยังไม่ได้ใช้งาน": https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

ความเชื่อที่ 2: StyleSheetตรวจสอบสไตล์อ็อบเจ็กต์ในเวลาคอมไพล์

นี่ไม่เป็นความจริง. JavaScript ธรรมดาไม่สามารถตรวจสอบความถูกต้องของวัตถุในเวลาคอมไพล์

สองสิ่ง:

  • มันตรวจสอบความถูกต้องที่รันไทม์ แต่เมื่อคุณส่งสไตล์อ็อบเจ็กต์ไปยังคอมโพเนนต์ ไม่แตกต่าง.
  • จะตรวจสอบความถูกต้องในเวลาคอมไพล์หากคุณใช้ Flow หรือ TypeScriptแต่จะทำเช่นนั้นเมื่อคุณส่งผ่านวัตถุเป็นสไตล์ prop ไปยังส่วนประกอบหรือถ้าคุณพิมพ์วัตถุอย่างถูกต้องเช่นด้านล่าง ไม่มีความแตกต่างทั้ง
const containerStyle: ViewStyle = {
   ...
}

3
จริง. บางทีความสับสนอาจมาจากเอกสารเวอร์ชันก่อนหน้าซึ่งหมายความว่าในที่สุดพวกเขาจะอ้างอิงสไตล์ตามรหัส ที่ไม่ได้กล่าวถึงในเอกสาร 0.59
eremzeit

1
THX สำหรับการทำให้เข้าใจผิด แต่คำถามเปิด - ทำเพื่ออะไร?
Vasiliy Vanchuk

1
บวกเกี่ยวกับ p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk

1
ดังนั้นการใช้ StyleSheet จึงสมบูรณ์ ... ไร้ประโยชน์?
Jose V

4
การทดสอบของฉันแสดงให้เห็นว่ามันไม่ตรวจสอบที่รันไทม์โดยไม่จำเป็นต้องส่งผ่านไปยังองค์ประกอบเช่นStyleSheet.create( {x:{flex: "1"}} )จะล้มเหลวที่รันไทม์เป็นจะตรวจสอบ typescript เกี่ยวกับเรื่องนี้ที่รวบรวมเวลา
Glenn Lawrence

24

คำตอบที่ยอมรับไม่ใช่คำตอบสำหรับคำถาม OP

คำถามไม่ใช่ความแตกต่างระหว่างรูปแบบอินไลน์กับconstภายนอกคลาส แต่ทำไมเราควรใช้StyleSheet.createแทนอ็อบเจกต์ธรรมดา

หลังจากค้นคว้าสิ่งที่ฉันพบมีดังต่อไปนี้ (โปรดอัปเดตหากคุณมีข้อมูลใด ๆ ) ข้อดีของStyleSheet.createควรมีดังต่อไปนี้:

  1. มันตรวจสอบสไตล์
  2. ความสมบูรณ์แบบที่ดีขึ้นเนื่องจากสร้างการแมปของสไตล์กับ ID จากนั้นจะอ้างถึงภายในด้วย ID นี้แทนที่จะสร้างทุกครั้งที่มีวัตถุใหม่ ดังนั้นแม้กระบวนการอัปเดตอุปกรณ์จะเร็วกว่าเพราะคุณไม่ได้ส่งทุกครั้งที่มีวัตถุใหม่ทั้งหมด

11
สิ่งเหล่านี้เป็นตำนาน ตรวจสอบคำตอบของฉัน
Nikola Mihajlović

ถ้าฉันกำหนดสไตล์อ็อบเจ็กต์นอกคลาส (หรือแม้กระทั่งเป็นคุณสมบัติคลาส) มันจะถูกสร้างขึ้นครั้งเดียว (หรือหนึ่งครั้งต่ออินสแตนซ์) อ็อบเจ็กต์เดียวกันที่ถูกสร้างขึ้นอีกครั้งจะเกี่ยวข้องกับฟังก์ชันภายในเท่านั้น
ThaJay

ใช่สำหรับ const แต่ไม่มีคุณสมบัติระดับ คุณสมบัติระดับคงที่ใช่
quirimmo

5

เคยมีการพิจารณาว่าการใช้ StyleSheet มีประสิทธิภาพมากกว่าและได้รับการ แนะนำด้วยเหตุผลนี้โดยทีมงาน RN จนถึงเวอร์ชัน 0.57 แต่ตอนนี้ไม่แนะนำอีกต่อไปเนื่องจากได้ระบุไว้อย่างถูกต้องในคำตอบอื่นสำหรับคำถามนี้

เอกสาร RNนี้แนะนำ StyleSheet ด้วยเหตุผลดังต่อไปนี้ แต่ผมคิดว่าเหตุผลเหล่านี้จะนำไปใช้อย่างเท่าเทียมกันกับวัตถุธรรมดาที่จะถูกสร้างขึ้นที่ด้านนอกของฟังก์ชั่นการแสดงผล:

  • การย้ายสไตล์ออกจากฟังก์ชันการแสดงผลจะทำให้คุณเข้าใจโค้ดได้ง่ายขึ้น
  • การตั้งชื่อสไตล์เป็นวิธีที่ดีในการเพิ่มความหมายให้กับส่วนประกอบระดับต่ำในฟังก์ชันการแสดงผล

ดังนั้นสิ่งที่ผมคิดว่าจะมีผลประโยชน์ที่เป็นไปได้ของการใช้ StyleSheet มากกว่าวัตถุธรรมดา?

1) แม้จะอ้างไปในทางตรงกันข้ามการทดสอบของฉันใน RN v0.59.10 บ่งบอกว่าคุณทำจะได้รับการตรวจสอบบางอย่างเมื่อเรียกStyleSheet.create()และ typescript (และอาจจะไหล) นอกจากนี้ยังจะรายงานข้อผิดพลาดที่รวบรวมเวลา แม้ว่าจะไม่มีการตรวจสอบเวลาคอมไพล์ฉันคิดว่าการตรวจสอบความถูกต้องของรูปแบบรันไทม์ก่อนที่จะใช้สำหรับการเรนเดอร์โดยเฉพาะอย่างยิ่งเมื่อส่วนประกอบที่ใช้สไตล์เหล่านั้นสามารถแสดงผลตามเงื่อนไขได้ วิธีนี้จะช่วยให้สามารถรับข้อผิดพลาดดังกล่าวได้โดยไม่ต้องทดสอบสถานการณ์การแสดงผลทั้งหมด

2) ระบุว่า StyleSheet ถูกแนะนำโดยทีมงาน RN ที่พวกเขาอาจจะยังคงมีความหวังของการใช้ StyleSheet ในการปรับปรุงประสิทธิภาพการทำงานในอนาคตและอาจมีการปรับปรุงไปได้อื่น ๆ ในใจเช่นกันตัวอย่างเช่น:

3) การStyleSheet.create()ตรวจสอบเวลาทำงานปัจจุบันมีประโยชน์ แต่มีข้อ จำกัด เล็กน้อย ดูเหมือนว่าจะ จำกัด เฉพาะการตรวจสอบประเภทที่คุณจะได้รับจากโฟลว์หรือ typescript ดังนั้นจะเลือกพูดflex: "1"หรือborderStyle: "rubbish"แต่ไม่ใช่width: "rubbish"เพราะอาจเป็นสตริงเปอร์เซ็นต์ เป็นไปได้ว่าทีม RN อาจปรับปรุงการตรวจสอบความถูกต้องดังกล่าวในอนาคตโดยการตรวจสอบสิ่งต่างๆเช่นสตริงเปอร์เซ็นต์หรือขีด จำกัด ช่วงหรือคุณสามารถรวมStyleSheet.create()ฟังก์ชันของคุณเองเพื่อทำการตรวจสอบความถูกต้องที่ครอบคลุมมากขึ้น

4) ด้วยการใช้ StyleSheet คุณอาจจะทำให้ง่ายต่อการเปลี่ยนไปใช้ทางเลือก / ส่วนขยายของบุคคลที่สามเช่นreact-native-Extended-stylesheetที่ให้มากขึ้น


1

การสร้างสไตล์ของคุณผ่านStyleSheet.createจะผ่านไปแม้ว่าจะมีการตรวจสอบความถูกต้องก็ต่อเมื่อตัวแปรส่วนกลาง__DEV__ถูกตั้งค่าเป็นจริง (หรือในขณะที่ทำงานในโปรแกรมจำลอง Android หรือ IOS ให้ดูที่ตัวแปร React Native DEV และ PROD )

ซอร์สโค้ดของฟังก์ชันนั้นค่อนข้างง่าย:

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;
}

ฉันอยากจะแนะนำให้ใช้เพราะมันทำการตรวจสอบเวลาทำงานในระหว่างการพัฒนาและยังหยุดวัตถุ


1

ฉันไม่พบความแตกต่างใด ๆ ระหว่างStyleSheetและวัตถุธรรมดายกเว้นการพิมพ์การตรวจสอบความถูกต้องใน TypeScript

ตัวอย่างเช่นสิ่งนี้ (สังเกตความแตกต่างในการพิมพ์):

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,
  },
});

เท่ากับสิ่งนี้:

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,
  },
};

ขอบคุณสำหรับตัวอย่าง TypeScript
ThaJay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.