วิธีที่ถูกต้องในการจัดการการจัดแต่งทรงผมตามเงื่อนไขใน React


95

ตอนนี้ฉันกำลังทำ React อยู่และฉันสงสัยว่ามีวิธี "ที่ถูกต้อง" ในการจัดแต่งทรงผมตามเงื่อนไขหรือไม่ ในบทช่วยสอนพวกเขาใช้

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

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


1
ฉันคิดว่าคุณอาจมีreduxและreactสับสน Redux ไม่มีส่วนเกี่ยวข้องกับการจัดแต่งทรงผม
rossipedia

3
ฉันคิดว่าความต้องการของคุณเป็นสิ่งที่จำเป็นสำหรับเอกสาร แต่กระตือรือร้นมากเกินไปสำหรับแอปพลิเคชันที่ใช้งานร่วมกันระหว่างการแลกเปลี่ยนมาร์กอัปไม่สำคัญ เว็บแอพหลักบางตัวกำลังกำจัดคลาสและใช้เฉพาะรูปแบบอินไลน์เท่านั้นซึ่งคาดเดาได้ง่ายกว่าและหาเหตุผลได้ง่ายกว่ากฎที่ใช้ 5 ข้อที่ทำให้ข้อความเป็นตัวหนา เมื่อ Attribs เป็นแบบไดนามิกคุณจะไม่ประหยัดแบนด์วิดท์มากเหมือนที่คุณทำกับเอกสารซ้ำ ๆ ความหมายของแอป (มาร์กอัปแหล่งที่มาของมุมมอง) ก็ไม่สำคัญเช่นกัน ...
dandavis

@rossipedia อ่าใช่ขอบคุณสับสนกำลังดูบทช่วยสอน redux เมื่อคิดถึงเรื่องนี้ขอบคุณ!
davidhtien

หากคุณไม่แน่ใจว่าค่าของการตกแต่งข้อความจะเป็นอย่างไรเนื่องจากการเรียงซ้อนและคุณต้องการใช้บรรทัดผ่านเท่านั้นหากสมบูรณ์เป็นจริงคุณจะต้องสร้างวัตถุสไตล์ ด้วยวิธีนี้คุณจะไม่ตั้งค่าเป็นไม่มีโดยบังเอิญเมื่อเป็นค่าอื่น const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Edward

คำตอบ:


78

หากคุณต้องการใช้ชื่อคลาสให้ใช้ชื่อคลาส

className={completed ? 'text-strike' : null}

คุณอาจพบว่าแพ็คเกจชื่อคลาสมีประโยชน์ ด้วยรหัสของคุณจะมีลักษณะดังนี้:

className={classNames({ 'text-strike': completed })}

ไม่มีวิธีที่ "ถูกต้อง" ในการจัดแต่งทรงผมตามเงื่อนไข ทำสิ่งที่ดีที่สุดสำหรับคุณ สำหรับตัวฉันเองฉันชอบที่จะหลีกเลี่ยงการจัดแต่งทรงผมแบบอินไลน์และใช้คลาสในลักษณะที่อธิบายไว้

POSTSCRIPT [06-AUG-2019]

ในขณะที่ยังคงเป็นความจริงที่ React ยังไม่ได้เปิดใช้งานเกี่ยวกับการจัดแต่งทรงผมวันนี้ฉันขอแนะนำโซลูชัน CSS-in-JS คือส่วนประกอบสไตล์หรืออารมณ์ความรู้สึก หากคุณเพิ่งเริ่มใช้ React ให้ใช้คลาส CSS หรือสไตล์อินไลน์เพื่อเริ่มต้น แต่เมื่อคุณคุ้นเคยกับ React แล้วฉันขอแนะนำให้ใช้ไลบรารีเหล่านี้ ฉันใช้มันในทุกโครงการ


สวัสดีถ้าคุณตัดสินใจใช้ className เป็นวิธีการจัดแต่งทรงผมตามเงื่อนไข โดยไม่ต้องclassNames lib. ฉันแนะนำให้คุณใช้undefinedแทนnull. classNameคุณสมบัติใช้เวลาเป็น input พิมพ์สตริงหรือไม่ได้กำหนด - ประเภท (String | undefined) - ⚡️
0xx

3
@JadRizk แนวทางที่ดีกว่าคืออย่าตั้ง className เลยถ้าคุณไม่มีค่าที่ถูกต้องให้ตั้งค่าเป็น const attrs = completed?{className:'text-strike'}:{}จากนั้น<li {...attrs}>text to maybe strike</li>(ตัวดำเนินการกระจาย) ด้วยวิธีนี้คุณจะไม่ตั้ง className เลยเว้นแต่คุณจะมีค่าที่ดีในการกำหนด นี่เป็นแนวทางที่สำคัญในการตั้งค่ารูปแบบอินไลน์ซึ่งคุณไม่สามารถทราบได้ว่าค่าปัจจุบันคืออะไร (เนื่องจาก CSS สามารถกำหนดได้ในไฟล์ที่คุณไม่สามารถควบคุมได้)
LinuxDisciple

@LinuxDisciple หากฟิลด์ทั้งหมดประเมินว่าเป็นเท็จก็classnamesส่งคืนสตริงว่าง สิ่งนี้จะไม่ได้รับผลกระทบจาก CSS ใด ๆ
David L. Walsh

@ DavidL.Walsh 21 ชั่วโมงที่แล้วฉันคิดว่าวิธีแก้ปัญหาของ JadRizk เป็นทางเลือกที่ผิดระหว่างnullและundefinedยังคงส่งผลให้classแอตทริบิวต์ไม่มีค่าใน html (เช่น<p class></p>แทนที่จะเป็น<p></p>) ดังนั้นฉันจึงจัดเตรียมวิธีที่หลีกเลี่ยงการตั้งค่าclassNameเลย อย่างที่เกิดขึ้นฉันคิดผิดเกี่ยวกับวิธีแก้ปัญหาของ JadRizk สำหรับปัญหาที่ระบุไว้ฉันเชื่อว่าการแก้ปัญหาของคุณด้วยการปรับแต่งของ JadRizk นั้นดีที่สุด ไวยากรณ์ของฉันสามารถกำหนดรายการอุปกรณ์ประกอบฉากและค่าตามเงื่อนไขได้ตามอำเภอใจ แต่การตั้งชื่อคลาสมากเกินไป
LinuxDisciple

106
 <div style={{ visibility: this.state.driverDetails.firstName != undefined? 'visible': 'hidden'}}></div>

ชำระเงินรหัสด้านบน ที่จะทำเคล็ดลับ


3
กำลังมองหาบางสิ่งเช่นนี้ การจัดแต่งทรงผมแบบมีเงื่อนไขขอบคุณ
Souvik Ghosh

<div style = {{visibility: this.state.driverDetails.firstName! == ไม่ได้กำหนด? 'visible': 'hidden'}}> </div> พิมพ์ผิดเล็กน้อยใน ==
vinayak shahdeo

31

หากคุณต้องการใช้สไตล์อินไลน์ตามเงื่อนไข (ใช้ทั้งหมดหรือไม่ใช้เลย) สัญกรณ์นี้จะใช้งานได้เช่นกัน:

style={ someCondition ? { textAlign:'center', paddingTop: '50%'} : {}}

ในกรณีที่ 'someCondition' ไม่เป็นจริงคุณจะส่งผ่านวัตถุว่างเปล่า


2
รูปแบบนี้ไม่สร้างความแตกต่างที่ไม่จำเป็นหรือไม่? ความเข้าใจของฉันเกี่ยวกับความแตกต่างของ DOM คือstyleprop ที่นี่มักจะเปลี่ยนไปตั้งแต่ใน Javascript {} != {} ถ้าฉันถูกต้องเกี่ยวกับความแตกต่างอาจจะดีกว่าถ้าใช้ " undefined" แทน " {}"
Dawson B

1
หมายเหตุที่ดี ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้
Vlado

8

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

<div className={{completed ? "completed" : ""}}></div>

สำหรับชุดสถานะที่ซับซ้อนมากขึ้นให้สะสมอาร์เรย์ของคลาสและนำไปใช้:

var classes = [];

if (completed) classes.push("completed");
if (foo) classes.push("foo");
if (someComplicatedCondition) classes.push("bar");

return <div className={{classes.join(" ")}}></div>;

6

แทนสิ่งนี้:

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

คุณสามารถลองทำสิ่งต่อไปนี้โดยใช้การลัดวงจร:

style={{
  textDecoration: completed && 'line-through'
}}

https://codeburst.io/javascript-short-circuit-conditionals-bbc13ac3e9eb

ข้อมูลสำคัญจากลิงค์:

การลัดวงจรหมายความว่าใน JavaScript เมื่อเราประเมินนิพจน์ AND (&&) หากตัวถูกดำเนินการแรกเป็นเท็จ JavaScript จะลัดวงจรและไม่ได้มองไปที่ตัวถูกดำเนินการที่สอง

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

วิธีแก้ปัญหาอื่น ๆ อาจเป็นแนวทางปฏิบัติที่ดีที่สุด แต่คิดว่าควรค่าแก่การแบ่งปัน


3

อีกวิธีหนึ่งโดยใช้สไตล์อินไลน์และตัวดำเนินการกระจาย

style={{
  ...completed ? { textDecoration: completed } : {}
}}

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


1
วิธีการที่ดีถ้าคุณไม่ต้องการที่จะเปลี่ยนรูปแบบเริ่มต้น
dhilt

2

ฉันเจอคำถามนี้ในขณะที่พยายามตอบคำถามเดียวกัน แนวทางของ McCrohan กับคลาสอาร์เรย์และการเข้าร่วมนั้นมั่นคง

จากประสบการณ์ของฉันฉันได้ทำงานกับรหัสทับทิมดั้งเดิมจำนวนมากที่ถูกแปลงเป็น React และในขณะที่เราสร้างส่วนประกอบขึ้นฉันพบว่าตัวเองกำลังเข้าถึงทั้งคลาส css ที่มีอยู่และสไตล์อินไลน์

ตัวอย่างข้อมูลโค้ดภายในคอมโพเนนต์:

// if failed, progress bar is red, otherwise green 
<div
    className={`progress-bar ${failed ? failed' : ''}`}
    style={{ width: this.getPercentage() }} 
/>

อีกครั้งฉันพบว่าตัวเองกำลังเข้าถึงรหัส css เดิม "บรรจุภัณฑ์" พร้อมกับส่วนประกอบและดำเนินการต่อไป

ดังนั้นฉันรู้สึกว่ามันเป็นเรื่องเล็กน้อยที่ "ดีที่สุด" เนื่องจากป้ายนั้นจะแตกต่างกันไปมากขึ้นอยู่กับโครงการของคุณ


คุณไม่ควรรวม classNames กับแอตทริบิวต์ style ซึ่งเป็นเรื่องที่วุ่นวาย
Sebastian Voráč

0

วิธีที่ดีที่สุดในการจัดการสไตล์คือการใช้คลาสที่มีคุณสมบัติ css

ตัวอย่าง:

<Component className={this.getColor()} />

getColor() {
    let class = "badge m2";
    class += this.state.count===0 ? "warning" : danger;
    return class;
}

0

คุณสามารถใช้บางสิ่งเช่นนี้

render () {
    var btnClass = 'btn';
    if (this.state.isPressed) btnClass += ' btn-pressed';
    else if (this.state.isHovered) btnClass += ' btn-over';
    return <button className={btnClass}>{this.props.label}</button>;
  }

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

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.