Cách đúng để xử lý kiểu có điều kiện trong React


95

Tôi đang làm một số React ngay bây giờ và tôi đã tự hỏi liệu có cách "chính xác" để tạo kiểu có điều kiện hay không. Trong hướng dẫn họ sử dụng

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

Tôi không thích sử dụng kiểu nội tuyến nên thay vào đó tôi muốn sử dụng một lớp để kiểm soát kiểu có điều kiện. Làm thế nào để tiếp cận điều này theo cách suy nghĩ của React? Hay tôi chỉ nên sử dụng cách tạo kiểu nội tuyến này?


1
Tôi nghĩ rằng bạn có thể có reduxreactbối rối. Redux không liên quan gì đến việc tạo kiểu.
rossipedia ngày

3
tôi nghĩ sở thích của bạn là phù hợp với các tài liệu, nhưng quá sốt sắng với các ứng dụng mà tính toán trao đổi đánh dấu không quan trọng. một số ứng dụng web lớn đang thực sự loại bỏ các lớp và chỉ sử dụng kiểu nội tuyến, dễ đoán hơn và dễ suy luận hơn so với quy tắc nào trong số 5 quy tắc được áp dụng là làm cho văn bản in đậm. khi tiêu hao là động, bạn không tiết kiệm được nhiều băng thông như khi làm với các tài liệu lặp đi lặp lại. ngữ nghĩa của ứng dụng (đánh dấu nguồn xem) cũng không quan trọng lắm ...
dandavis

@rossipedia à vâng, cảm ơn bạn, tôi rất bối rối, đã xem hướng dẫn về redux khi nghĩ về điều này, cảm ơn bạn!
davidhtien

Nếu bạn không chắc chắn giá trị của trang trí văn bản sẽ như thế nào vì sự phân tầng và bạn chỉ muốn áp dụng một đường thẳng nếu hoàn thành là đúng, bạn sẽ phải xây dựng một đối tượng kiểu. Bằng cách này, bạn không vô tình đặt nó thành không khi nó là một giá trị khác. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Edward

Câu trả lời:


78

Nếu bạn thích sử dụng tên lớp, hãy sử dụng tên lớp.

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

Bạn cũng có thể thấy gói tên lớp hữu ích. Với nó, mã của bạn sẽ giống như sau:

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

Không có cách nào "đúng" để tạo kiểu có điều kiện. Làm bất cứ điều gì tốt nhất cho bạn. Đối với bản thân tôi, tôi muốn tránh tạo kiểu nội tuyến và sử dụng các lớp theo cách vừa được mô tả.

POSTSCRIPT [06-AUG-2019]

Mặc dù vẫn đúng là React chưa được khai thác tối đa về kiểu dáng, nhưng những ngày này, tôi muốn giới thiệu giải pháp CSS-in-JS; cụ thể là các thành phần hoặc cảm xúc được tạo kiểu . Nếu bạn chưa quen với React, hãy theo dõi các lớp CSS hoặc các kiểu nội tuyến để bắt đầu. Nhưng một khi bạn cảm thấy thoải mái với React, tôi khuyên bạn nên sử dụng một trong những thư viện này. Tôi sử dụng chúng trong mọi dự án.


Xin chào, nếu bạn quyết định sử dụng className làm phương pháp tạo kiểu có điều kiện. Nếu không có classNames lib. Tôi khuyên bạn nên sử dụng undefinedthay vì null. Các classNametài sản mất như là đầu vào gõ một String hoặc không xác định - loại (String | undefined) - ⚡️
0xx

3
@JadRizk cách tiếp cận tốt hơn nữa là hoàn toàn không đặt className nếu bạn không có giá trị hợp lệ để đặt nó. const attrs = completed?{className:'text-strike'}:{}sau đó <li {...attrs}>text to maybe strike</li>(toán tử spread). Bằng cách đó, bạn hoàn toàn không đặt className trừ khi bạn có một giá trị tốt để gán. Đây là một cách tiếp cận quan trọng để thiết lập một số kiểu nội tuyến mà bạn không thể biết giá trị hiện tại là gì (vì nó có thể được đặt bởi CSS trong một tệp mà bạn có thể không kiểm soát).
LinuxDisciple

@LinuxDisciple nếu tất cả các trường đánh giá thành falsey thì classnameschỉ trả về một chuỗi trống. Điều này sẽ không bị ảnh hưởng bởi bất kỳ CSS nào.
David L. Walsh

@ DavidL.Walsh 21 giờ trước, tôi nghĩ rằng giải pháp của JadRizk là một lựa chọn sai lầm giữa nullundefinedđiều đó vẫn sẽ dẫn đến classthuộc tính không có giá trị trong html (tức là <p class></p>thay vì <p></p>) vì vậy tôi đã cung cấp một phương pháp tránh được việc đặt className. Khi nó xảy ra, tôi đã sai về giải pháp của JadRizk. Đối với vấn đề đã nêu, tôi tin rằng giải pháp của bạn với sự tinh chỉnh của JadRizk là tốt nhất. Cú pháp của tôi có thể đặt danh sách đạo cụ tùy ý và giá trị của chúng theo điều kiện, nhưng nó quá mức cần thiết khi chỉ đặt tên lớp.
LinuxDisciple

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

Kiểm tra mã trên. Điều đó sẽ làm các thủ thuật.


3
Chính xác là đang tìm kiếm một cái gì đó như thế này. Tạo kiểu nội tuyến có điều kiện, cảm ơn bạn.
Souvik Ghosh

<div style = {{display: this.state.driverDetails.firstName! == undefined? 'hidden': 'hidden'}}> </div>. Lỗi chính tả nhỏ ==.
vinayak shahdeo

31

Nếu bạn cần áp dụng các kiểu nội tuyến có điều kiện (áp dụng tất cả hoặc không áp dụng) thì ký hiệu này cũng hoạt động:

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

Trong trường hợp 'someCondition' không được thực hiện thì bạn chuyển đối tượng trống.


2
Mặc dù vậy, mẫu này không tạo ra sự khác biệt không cần thiết? Sự hiểu biết của tôi về DOM diffing là stylechỗ dựa ở đây sẽ luôn luôn thay đổi vì trong Javascript {} != {} Nếu tôi đúng về diffing, có lẽ nó tốt hơn để sử dụng " undefined" thay vì " {}"
Dawson B

1
Lưu ý tốt. Tôi không chắc chắn về điều này.
Vlado

8

Đầu tiên, tôi đồng ý với bạn về vấn đề phong cách - tôi cũng sẽ (và thực sự) áp dụng có điều kiện các lớp thay vì các kiểu nội tuyến. Nhưng bạn có thể sử dụng cùng một kỹ thuật:

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

Đối với các tập hợp trạng thái phức tạp hơn, hãy tích lũy một mảng các lớp và áp dụng chúng:

var classes = [];

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

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

6

thay vì cái này:

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

bạn có thể thử những cách sau bằng cách sử dụng đoản mạch:

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

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

bit thông tin quan trọng từ liên kết:

Ngắn mạch có nghĩa là trong JavaScript khi chúng ta đánh giá biểu thức AND (&&), nếu toán hạng đầu tiên là sai, JavaScript sẽ đoản mạch và thậm chí không nhìn vào toán hạng thứ hai.

Cần lưu ý rằng điều này sẽ trả về false nếu toán hạng đầu tiên là false, vì vậy có thể phải xem xét điều này sẽ ảnh hưởng đến phong cách của bạn như thế nào.

Các giải pháp khác có thể là phương pháp hay nhất, nhưng tôi nghĩ rằng nó sẽ đáng được chia sẻ.


3

Một cách khác, sử dụng kiểu nội tuyến và toán tử spread

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

Cách đó hữu ích trong một số trường hợp mà bạn muốn thêm một loạt thuộc tính cùng lúc dựa trên điều kiện.


1
Cách tiếp cận tốt nếu bạn không muốn thay đổi kiểu mặc định
dhilt

2

Tôi đã gặp câu hỏi này trong khi cố gắng trả lời cùng một câu hỏi. Cách tiếp cận của McCrohan với mảng & nối các lớp là rất vững chắc.

Qua kinh nghiệm của mình, tôi đã làm việc với rất nhiều mã ruby ​​cũ đang được chuyển đổi sang React và khi chúng tôi xây dựng (các) thành phần, tôi thấy mình đang tiếp cận với cả các lớp css hiện có và các kiểu nội tuyến.

đoạn mã ví dụ bên trong một thành phần:

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

Một lần nữa, tôi thấy mình đang tiếp cận với mã css cũ, "đóng gói" nó với thành phần và tiếp tục.

Vì vậy, tôi thực sự cảm thấy rằng điều gì là "tốt nhất" cũng có chút băn khoăn vì nhãn đó sẽ thay đổi rất nhiều tùy thuộc vào dự án của bạn.


Bạn không nên kết hợp với classnames thuộc tính phong cách, mà của cắn của một mớ hỗn độn
Sebastian Voráč

0

Cách tốt nhất để xử lý kiểu là sử dụng các lớp có tập hợp các thuộc tính css.

thí dụ:

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

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

0

Bạn có thể sử dụng những thứ như thế này.

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

Hoặc nếu không, bạn có thể sử dụng gói NPM tên lớp để làm cho các đạo cụ className động và có điều kiện hoạt động đơn giản hơn (đặc biệt hơn so với thao tác chuỗi có điều kiện).

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'
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.