Tạo ứng dụng React từ đầu (Phần 7): Thiết lập React và Thực tiễn tốt nhất

Bài đăng này là một phần của loạt bài viết dành cho người mới bắt đầu dành cho những người sử dụng
các công cụ, mẫu hoặc mẫu soạn sẵn cho React nhưng muốn tìm hiểu và hiểu cách xây dựng ứng dụng React ngay từ đầu.

Tất cả các bài viết trong loạt bài này:
Phần 1: Giới thiệu
Phần 2: Khởi tạo và tệp đầu tiên
Phần 3: Sử dụng Cú pháp ES2015
Phần 4: Thực thi Hướng dẫn về Phong cách
Phần 5: Thiết lập Máy chủ Express
Phần 6: Sử dụng Mô-đun Bundler
Phần 7: Thiết lập phản ứng và thực tiễn tốt nhất
Phần 8: Thiết lập Redux
Phần 9: Thiết lập Bộ định tuyến React
Phần 10: TDD và thiết lập Jest

Thiết lập React

Trong bài đăng này, chúng tôi sẽ thiết lập React và tạo một thành phần rất đơn giản sau đó chúng tôi sẽ thực hiện một số thực tiễn tốt nhất mà bạn nên ghi nhớ khi phát triển các thành phần React. Đây là nơi phần thú vị bắt đầu, vì vậy hãy để chúng tôi khai thác ngay!

Cài đặt các gói React và React Dom làm phụ thuộc:

$ npm cài đặt - phản ứng phản ứng-dom

Sau đó mở index.js và tạo một thành phần React rất đơn giản đại diện cho ứng dụng của chúng tôi. Chúng tôi đã có một phần tử với ứng dụng id trong tệp mẫu index.pug của chúng tôi, vì vậy hãy cho chúng tôi sử dụng nó để gắn kết ứng dụng.

/ **
 * index.js
 * /
nhập React từ 'Reac';
nhập {render} từ 'Reac-dom';
const MainApp = () => (
  

Xin chào Phản ứng! );

// kết xuất ứng dụng
kết xuất (, document.getEuityById ('ứng dụng'));

Mã đơn giản này tạo ra một thành phần chức năng phi trạng thái MainApp và gắn nó vào một phần tử DOM có ứng dụng id. Mã này sẽ không hoạt động ngay lập tức và bạn sẽ gặp lỗi nếu bạn cố gắng xây dựng gói hoặc khởi động máy chủ.

Lý do cho lỗi này là chúng tôi có cú pháp JSX bên trong tệp index.js mà Babel chưa hiểu. Để cho phép Babel diễn giải cú pháp này thành JavaScript thông thường, chúng tôi sẽ sử dụng cài đặt sẵn React cho Babel.

Cài đặt gói như một phụ thuộc:

$ npm cài đặt - babave-preset-Reac

Sau đó thêm cài đặt trước vào danh sách các cài đặt trước trong tệp .babelrc:

{
  "cài đặt trước": [
    "es2015",
    "giai đoạn-0",
    "phản ứng"
  ],
  "plugin": ["biến đổi nội tuyến-biến-môi trường"]
}

Cũng có một lỗi linting sẽ ngăn bạn xây dựng gói. Kẻ nói dối đang phàn nàn vì index.js là một tệp JavaScript chứa cú pháp JSX nhưng sử dụng phần mở rộng js thay vì jsx.

Bạn có thể đọc mô tả cho quy tắc này ở đây. Phần ‘Khi không sử dụng phần Phần mềm nói rằng bạn không nên sử dụng quy tắc này nếu bạn không quan tâm đến việc hạn chế phần mở rộng của các tệp có chứa cú pháp JSX.

Bạn có thể tiếp tục sử dụng quy tắc này nhưng tôi thích sử dụng tiện ích mở rộng js cho tất cả các tệp vì vậy tôi sẽ tắt quy tắc này:

{
  "kéo dài": "airbnb",
  "env": {
    "es6": đúng,
    "trình duyệt": đúng,
    "nút": đúng
  },
  "quy tắc": {
    "Reac / jsx-filename-extension": 0
  }
}

Kích hoạt HMR

Kích hoạt thay thế mô-đun nóng đơn giản như thêm một khối mã:

/ **
 * index.js
 * /
nhập React từ 'Reac';
nhập {render} từ 'Reac-dom';
if (module.hot) {
  mô-đun.hot.accept ();
}
const MainApp = () => (
  

Xin chào Phản ứng! );

// kết xuất ứng dụng
kết xuất (, document.getEuityById ('ứng dụng'));

Lời khuyên và thực tiễn tốt nhất

Trước khi tiếp tục với hướng dẫn, chúng tôi sẽ đi qua một danh sách tổng hợp các mẹo và thực tiễn tốt nhất mà tôi đã học được từ kinh nghiệm làm việc với React và cả từ việc đọc và tìm kiếm trên web. Hãy ghi nhớ những điều đó khi bạn đang tạo các thành phần React của mình.

Nhập khẩu phụ thuộc so với nhập khẩu địa phương

Phân tách nhập khẩu phụ thuộc từ nhập khẩu địa phương bằng một dòng mới. Nhập khẩu phụ thuộc nên đến đầu tiên.

nhập React, {Thành phần} từ 'Reac';
nhập mô hình hữu ích từ 'mô-đun hữu ích';
nhập myLocalModule từ './my-local-module';

Thành phần chức năng không quốc tịch

Nếu thành phần là thành phần chỉ hiển thị hoặc không cần sử dụng Đối tượng trạng thái, hãy sử dụng hàm JavaScript đơn giản thay vì một lớp. Đây được gọi là Thành phần chức năng không quốc tịch.

Vì vậy, thay vì làm điều này:

nhập React, {Thành phần} từ 'Reac';
lớp MyComponent mở rộng Thành phần {
  kết xuất () {
    trở về (
      
Xin chào!     );   } }
xuất mặc định MyComponent;

Làm cái này:

nhập React từ 'Reac';
const MyComponent = () => 
Xin chào! ;
xuất mặc định MyComponent;

Xem bao nhiêu lộn xộn đã được gỡ bỏ? Bạn cũng có thể làm cho nó đơn giản hơn bằng cách xuất chính hàm:

nhập React từ 'Reac';
xuất mặc định () => 
Xin chào! ;

Tuy nhiên, tôi không thích làm điều này vì nó làm cho việc gỡ lỗi khó hơn. Nếu bạn kiểm tra React Dev Tools, bạn sẽ thấy tên thành phần đó là Unknown Unknown vì hàm này là ẩn danh.

Thành phần chức năng ẩn danh

Cách tiếp cận tốt hơn sẽ là sử dụng hàm có tên bình thường thay vì hàm ẩn danh:

nhập React từ 'Reac';
xuất hàm mặc định MyComponent () {
  trả lại 
Xin chào! ; }
Thành phần chức năng được đặt tên

Bắt đầu với các thành phần trình bày

Các thành phần trình bày đơn giản hơn để định nghĩa, dễ hiểu hơn và có thể được sử dụng lại nhiều lần vì chúng độc lập với phần còn lại của ứng dụng.

Nếu bạn chia ứng dụng của mình thành một tập hợp các thành phần trình bày, bạn có thể đặt tất cả chúng trên một trang và điều chỉnh thiết kế và các biến thể của chúng để thực hiện giao diện thống nhất trong toàn bộ ứng dụng.

Xây dựng thành phần của bạn như một thành phần trình bày và chỉ thêm trạng thái khi bạn cần, điều này đưa chúng ta đến mẹo tiếp theo.

Giảm thiểu việc sử dụng nhà nước

Sử dụng trạng thái một cách tiết kiệm trong các thành phần của bạn và đảm bảo rằng chúng sử dụng trạng thái cho UI chứ không phải dữ liệu, nói cách khác, nếu bạn không sử dụng nó trong render () thì nó không nên ở trạng thái. Hãy nhớ rằng bạn chỉ nên sử dụng setState nếu bạn muốn kết xuất lại thành phần của mình.

Hãy để chúng tôi nói rằng chúng tôi có một thành phần bao gồm một nút duy nhất. Nút này chỉ có thể được bấm một lần và khi được nhấp, một thông báo sẽ được ghi vào bảng điều khiển:

nhập React, {Thành phần} từ 'Reac';

lớp MyComponent mở rộng Thành phần {
  bang = {
    clickedce: sai,
  };
  xử lýClick = () => {
    if (! this.state.clickyOnce) {
      console.log ('Đã nhấp');
    }
    this .setState ({
      clickedce: đúng,
    });
  }
  thành phầnDidUpdate () {
    console.log ('Đã cập nhật!');
  }
  kết xuất () {
    trở về (
      
         Nhấp vào tôi            );   } }
xuất mặc định MyComponent;

Đây là một ví dụ về việc triển khai kém, sử dụng trạng thái để đặt cờ clickedOnce, xác định xem nút có thể được nhấp lại hay không. Mỗi lần nhấn nút, thành phần sẽ kết xuất lại mặc dù không cần.

Ứng dụng này hiển thị lại trên nút bấm

Điều này sẽ tốt hơn:

nhập React, {Thành phần} từ 'Reac';

lớp MyComponent mở rộng Thành phần {
  clickedce = false;
  
  xử lýClick = () => {
    if (! this.clickOnce) {
      console.log ('Đã nhấp');
    }
    this .clickOnce = true;
  }
  thành phầnDidUpdate () {
    console.log ('Đã cập nhật!');
  }
  kết xuất () {
    trở về (
      
         Nhấp vào tôi            );   } }
xuất mặc định MyComponent;

Việc triển khai này sử dụng một thuộc tính lớp thay vì khóa trạng thái vì cờ clickedOnce không đại diện cho trạng thái UI và do đó không nên sống bên trong trạng thái thành phần. Với triển khai mới này, nhấp vào nút nhiều lần không còn kích hoạt cập nhật.

Luôn xác định propTypes và defaultProps

Tất cả các thành phần nên có propTypes và defaultProps được xác định càng cao càng tốt trong thành phần. Chúng phục vụ như tài liệu thành phần và sẽ được hiển thị ngay lập tức cho các nhà phát triển khác đang đọc tệp.

Kể từ React v15.5, React.PropTypes đã chuyển sang một gói khác, vì vậy chúng ta hãy cài đặt gói đó như một phụ thuộc:

$ npm cài đặt - loại prop -ave

Đối với các thành phần chức năng không trạng thái:

Các hàm được nâng lên trong JavaScript, có nghĩa là bạn có thể sử dụng một hàm trước khi khai báo:

nhập React từ 'Reac';
nhập PropTypes từ 'loại prop';
MyComponent.propTypes = {
  tiêu đề: PropTypes.opes,
};
MyComponent.defaultProps = {
  tiêu đề: 'Một bộ đếm đơn giản',
};
xuất hàm mặc định MyComponent (props) {
  trả về 

{props.title} ; }

ESLint sẽ phàn nàn về việc sử dụng hàm trước định nghĩa của nó nhưng vì lợi ích của tài liệu thành phần tốt hơn, chúng ta hãy vô hiệu hóa quy tắc linting này cho các hàm bằng cách sửa đổi tệp .eslintrc:

{
  ...
  "quy tắc": {
    "Reac / jsx-filename-extension": 0,
    "không sử dụng trước khi xác định": [
      "lỗi",
      {
        "chức năng": sai
      }
    ]
  }
}

Đối với các thành phần dựa trên lớp:

Không giống như các hàm, các lớp trong JavaScript không được nâng lên, vì vậy chúng ta không thể đơn giản thực hiện MyComponent.propTypes = ... trước khi xác định chính lớp đó nhưng chúng ta có thể định nghĩa propTypes và defaultProps là thuộc tính của lớp tĩnh:

nhập React, {Thành phần} từ 'Reac';
nhập PropTypes từ 'loại prop';
lớp MyComponent mở rộng Thành phần {
  propTypes tĩnh = {
    tiêu đề: PropTypes.opes,
  };
  defaultProps = {
    tiêu đề: 'Một bộ đếm đơn giản',
  };
  kết xuất () {
    trả về 

{this.props.title} ;   } }

xuất mặc định MyComponent;

Khởi nghiệp

Trạng thái có thể được khởi tạo trong hàm tạo thành phần:

lớp MyComponent mở rộng Thành phần {
  constructor (đạo cụ) {
    siêu (đạo cụ);
    this .state = {
      đếm: 0,
    };
  }
}

Một cách tốt hơn là khởi tạo trạng thái như một thuộc tính lớp:

lớp MyComponent mở rộng Thành phần {
  constructor (đạo cụ) {
    siêu (đạo cụ);
  }
  bang = {
    đếm: 0,
  };
}

Điều này có vẻ tốt hơn, sạch hơn, dễ đọc hơn và cũng đóng góp cho tài liệu thành phần. Đối tượng trạng thái nên được khởi tạo sau propTypes và defaultProps:

nhập React, {Thành phần} từ 'Reac';
nhập PropTypes từ 'loại prop';
lớp MyComponent mở rộng Thành phần {
  // propTypes đến trước
  propTypes tĩnh = {
    tiêu đề: PropTypes.opes,
  };
  // defaultProps đứng thứ hai
  defaultProps = {
    tiêu đề: 'Một bộ đếm đơn giản',
  };
  // constructor đến đây
  constructor() {
    ...
  }
  // sau đó đến trạng thái
  bang = {
    đếm: 0,
  };
}

Truyền một hàm cho setState

Tài liệu React không khuyến khích dựa vào giá trị this.state và this.props để tính toán trạng thái tiếp theo vì React cập nhật chúng không đồng bộ. Điều đó có nghĩa là trạng thái có thể không thay đổi ngay lập tức sau khi gọi setState ().

lớp MyComponent mở rộng Thành phần {
  bang = {
    đếm: 10,
  }
  onClick = () => {
    console.log (this.state.count); // 10
    
    // tính sẽ không thay đổi ngay lập tức
    this .setState ({Count: this.state.count + this.props.step});
    
    console.log (this.state.count); // vẫn là 10
  }
}

Mặc dù điều này hoạt động cho các kịch bản đơn giản và trạng thái vẫn sẽ được cập nhật chính xác, nhưng nó có thể dẫn đến hành vi không mong muốn trong các kịch bản phức tạp hơn.

Hãy xem xét kịch bản này, bạn có một thành phần biểu hiện một nút duy nhất. Khi nhấp vào nút này, một phương thức handleClick được gọi là:

lớp MyComponent mở rộng Thành phần {
  defaultProps = {
    bước: 5,
  }
  propTypes tĩnh = {
    bước: PropTypes.number,
  }
  
  bang = {
    đếm: 10,
  }
  
  xử lýClick = () => {
    this.doSthing ();
    this.doSthingElse ();
  }
  doS Something = () => {
    this .setState ({Count: this.state.count + this.props.step});
  }
  doS SomethingElse = () => {
    this .setState ({Count: this.state.count - 1});
  }
  kết xuất () {
    trở về (
      
        

Số hiện tại là: {this.state.count}          Nhấp vào tôi            );   } }

Nút gọi handleClick () khi được nhấp, lần lượt gọi doS Something () sau đó doS SomethingElse (). Cả hai hàm sẽ sửa đổi giá trị đếm bên trong trạng thái.

Theo logic, 10 + 5 là 15 thì trừ 1 và kết quả sẽ là 14, phải không? Chà, trong trường hợp này thì không phải - giá trị của số đếm sau lần nhấp đầu tiên là 9, không phải 14. Điều này xảy ra vì giá trị của this.state.count vẫn là 10 khi gọi doS SomethingElse () chứ không phải 15.

Để khắc phục điều này, bạn có thể sử dụng một dạng thứ hai của setState () chấp nhận một hàm chứ không phải là một đối tượng. Hàm đó sẽ nhận trạng thái trước làm đối số thứ nhất và các đạo cụ tại thời điểm cập nhật được áp dụng làm đối số thứ hai:

this .setState ((trướcState, đạo cụ) => ({
  đếm: trướcState.count + props.step
}))

Chúng tôi có thể sử dụng mẫu này để sửa ví dụ của chúng tôi:

lớp MyComponent mở rộng Thành phần {
  ...
  xử lýClick = () => {
    this.doSthing ();
    this.doSthingElse ();
  }
  doS Something = () => {
    this .setState ((trướcState, đạo cụ) => ({
      đếm: trướcState.count + props.step
    }));
  }
  doS SomethingElse = () => {
    this .setState (trướcState => ({
      đếm: trướcState.count - 1
    }));
  }
  ...
}

Với việc thực hiện này, số lượng được cập nhật đúng từ 10 đến 14 đến 18, v.v. Toán đơn giản có ý nghĩa một lần nữa!

Sử dụng các hàm mũi tên làm thuộc tính lớp

Từ khóa này luôn gây nhầm lẫn cho các nhà phát triển JavaScript và hành vi của nó không ít gây nhầm lẫn trong các thành phần React. Bạn có biết từ khóa này thay đổi như thế nào trong thành phần React không? Hãy xem xét ví dụ sau:

nhập React, {Thành phần} từ 'Reac';
lớp MyComponent mở rộng Thành phần {
  bang = {
    đếm: 0,
  };
  trong một cái nhấp chuột() {
    console.log (this.state);
  }
  kết xuất () {
    trở về (
      
        

Đếm là: {this.state.count}          Nhấp vào tôi            );   } }

xuất mặc định MyComponent;

Nhấp vào nút sẽ dẫn đến một lỗi:

Uncaught TypeError: Không thể đọc thuộc tính ‘trạng thái không xác định

Điều này là do onClick, như một phương thức lớp, không bị ràng buộc theo mặc định. Có một vài cách để sửa lỗi này. (ý định chơi chữ, có được không?)

Một cách là liên kết hàm với ngữ cảnh chính xác khi bạn chuyển nó vào bên trong hàm render ():

Hoặc bạn có thể tránh thay đổi ngữ cảnh bằng cách sử dụng hàm mũi tên trong render ():

 this.onClick (e)}> Nhấp vào tôi 

Tuy nhiên, hai phương thức này có chi phí hiệu năng nhẹ vì chức năng sẽ được phân bổ lại trên mỗi kết xuất. Để tránh chi phí hiệu năng nhỏ này, bạn có thể liên kết hàm bên trong hàm tạo:

nhập React, {Thành phần} từ 'Reac';
lớp MyComponent mở rộng Thành phần {
  constructor (đạo cụ) {
    siêu (đạo cụ);
    this .onClick = this.onClick.bind (this);
  }
  ...
  kết xuất () {
    ...
     Nhấp vào tôi 
    ...
  }
}
xuất mặc định MyComponent;

Kỹ thuật này tốt hơn nhưng bạn có thể dễ dàng thực hiện và kết thúc với một thứ giống như thế này:

constructor (đạo cụ) {
  // điều này thật tệ, thật tệ
  this .onClick = this.onClick.bind (this);
  this .onChange = this.onChange.bind (this);
  this .onSubmit = this.onSubmit.bind (this);
  this .increasCount = this.increasCount.bind (this);
  this.decreasCount = this.decreasCount.bind (this);
  this .resetCount = this.resetCount.bind (this);
  ...
}

Vì chúng tôi sử dụng Babel và có hỗ trợ cho các thuộc tính của lớp, cách tốt hơn là sử dụng các hàm mũi tên khi xác định các phương thức lớp:

lớp MyComponent mở rộng Thành phần {
  ...
  onClick = () => {
    // 'cái này' được bảo tồn
    console.log (this.state);
  }
  kết xuất () {
    trở về (
      
        

{this.state.count}          Nhấp vào tôi            );   } }

Phá hủy đối tượng đạo cụ

Khi một thành phần có nhiều đạo cụ, phá hủy đối tượng đạo cụ đặt từng thuộc tính trên dòng riêng của nó.

Đối với các thành phần chức năng không trạng thái:

xuất hàm mặc định MyComponent ({
  tên đầu tiên,
  Họ,
  địa chỉ email,
  sự miêu tả,
  thay đổi,
  gửi,
}) {
  trở về (
    
      

{FirstName}       ...        ); }

Đối số mặc định không phải là lý do để bỏ defaultProps. Như đã đề cập trước đó, bạn phải luôn xác định propTypes và defaultProps.

Đối với các thành phần dựa trên lớp:

lớp MyComponent mở rộng Thành phần {
  ...
  kết xuất () {
    hằng số {
      tên đầu tiên,
      Họ,
      địa chỉ email,
      sự miêu tả,
      thay đổi,
      gửi,
    } = this.props;
    trở về (
      
        

{FirstName}         ...            );   } }

Điều này sạch hơn, giúp dễ dàng sắp xếp lại các thuộc tính và giúp dễ dàng thêm / xóa các thuộc tính vào / khỏi danh sách trong khi tạo ra một khác biệt có thể đọc được cho Git. Hãy xem xét những điều sau đây:

Diff-ing dễ đọc hơn khi mỗi thuộc tính nằm trên một dòng mới

Ở phía bên tay phải, bạn có thể dễ dàng biết được thuộc tính nào đã được thêm vào, tuy nhiên, ở phía bên trái bạn chỉ biết rằng có gì đó đã thay đổi trên dòng đó và bạn phải xem xét thật kỹ để tìm ra phần nào của dòng đã thay đổi

Kết xuất có điều kiện

Khi bạn cần kết xuất một trong hai thành phần hoặc khối mã JSX dựa trên một điều kiện, hãy sử dụng biểu thức ternary:

được đăng nhập
  ? 
Chào mừng, {tên người dùng}!   : Đăng nhập

Nếu mã bao gồm nhiều hơn một dòng, hãy sử dụng dấu ngoặc đơn:

Được đăng nhập? (
  
    Chào mừng, {tên đăng nhập}!    ): (        Đăng nhập    )

Nếu bạn cần kết xuất một thành phần hoặc một khối mã JSX dựa trên một điều kiện, hãy sử dụng đánh giá ngắn mạch thay thế:

isComplete && 
Bạn đã hoàn tất!

Đối với nhiều hơn một dòng, sử dụng dấu ngoặc đơn:

hoàn tất && (
  
    Bạn xong việc rồi!    )

Thuộc tính chính

Đây là một mẫu phổ biến để sử dụng Array.prototype.map và các phương thức mảng tương tự bên trong hàm render () và rất dễ quên về thuộc tính khóa. Hòa giải đã đủ khó, đừng làm nó khó hơn. Luôn nhớ đặt chìa khóa nơi nó thuộc về. (chơi chữ có ý định một lần nữa, hiểu không?)

kết xuất () {
  trở về (
    
    {       {         item.map (mục => (           
  •             {Tên mục}                    ))        }        ); }

Khi bạn sử dụng map (), filter () hoặc các phương thức mảng tương tự, tham số thứ hai cho cuộc gọi lại là chỉ mục của mục. Nói chung là một ý tưởng tồi để sử dụng chỉ số này như là một chìa khóa. React sử dụng thuộc tính khóa để xác định mục nào đã thay đổi, đã được thêm hoặc đã bị xóa và giá trị khóa phải ổn định và sẽ xác định duy nhất từng mục.

Trong trường hợp mảng được sắp xếp hoặc một phần tử được thêm vào đầu mảng, chỉ mục sẽ được thay đổi mặc dù phần tử đại diện cho chỉ mục đó có thể giống nhau. Điều này dẫn đến kết xuất không cần thiết và trong một số trường hợp dẫn đến hiển thị dữ liệu sai.

Sử dụng UUID hoặc ShortID để tạo một id duy nhất cho mỗi mục khi nó được tạo lần đầu tiên và sử dụng nó làm giá trị khóa.

Bình thường hóa nhà nước

Cố gắng bình thường hóa đối tượng trạng thái và giữ cho nó càng phẳng càng tốt. Dữ liệu lồng trong trạng thái có nghĩa là logic phức tạp hơn được yêu cầu để cập nhật nó. Hãy tưởng tượng nó sẽ xấu đến mức nào khi cập nhật một trường được lồng sâu - chờ đợi, đừng tưởng tượng, ở đây:

// đối tượng trạng thái
bang = {
  ...
  bài viết: [
    ...,
    {
      meta: {
        id: 12,
        tác giả: '...',
        công khai: sai,
        ...
      },
      ...
    },
    ...
  ],
  ...
};
// để cập nhật 'công khai' thành 'đúng'
this .setState ({
  ... cái này
  bài viết: [
    ... this.state.posts.slice (0, chỉ mục),
    {
      ... this.state.posts [index],
      meta: {
        ... this.state.posts [index] .meta,
        công khai: đúng,
      }
    },
    ... this.state.posts.slice (index + 1),
  ]
});

Mã này không chỉ xấu, mà còn có thể buộc các thành phần không liên quan phải kết xuất lại ngay cả khi dữ liệu họ đang hiển thị không thực sự thay đổi. Điều này là do chúng tôi đã cập nhật tất cả các tổ tiên trong cây trạng thái với các tham chiếu đối tượng mới.

Cập nhật cùng một trường sẽ đơn giản hơn nếu chúng ta cấu trúc lại cây trạng thái:

bang = {
  bài viết: [
    10,
    11,
    12,
  ],
  meta: {
    10: {
      id: 10,
      tác giả: 'tác giả-a',
      công khai: sai,
    },
    11: {
      id: 11,
      tác giả: 'tác giả-b',
      công khai: sai,
    },
    12: {
      id: 12,
      tác giả: 'tác giả-c',
      công khai: sai,
    },
  },
}
this .setState ({
  meta: {
    ... này.state.meta,
    [Tôi]: {
      ... này.state.meta [id],
      công khai: đúng,
    }
  }
})

Sử dụng tên lớp

Nếu bạn đã từng ở trong một tình huống mà bạn cần sử dụng một tên lớp có điều kiện, bạn có thể đã viết một cái gì đó trông như thế này:

  ...

Điều này trở nên thực sự xấu xí nếu bạn có nhiều tên lớp có điều kiện. Thay vì sử dụng một ternary, hãy sử dụng gói tên lớp:

nhập tên lớp từ 'tên lớp';
const class = classnames ('tab', {'is-active': isActive});
  ...

Một thành phần cho mỗi tệp

Đây không phải là một quy tắc cứng nhưng tôi thích giữ mỗi thành phần trong một tệp và xuất mặc định thành phần đó. Tôi không có lý do cụ thể cho việc này nhưng tôi chỉ thấy nó sạch sẽ và có tổ chức hơn - cao năm nếu bạn cũng làm điều đó!

Phần kết luận

Không có một cách đúng để phát triển thành phần React. Chúng tôi đã trải qua một vài thực tiễn và mô hình tốt nhất sẽ giúp bạn phát triển các thành phần có thể tái sử dụng và bảo trì và tôi rất tò mò muốn biết loại mô hình và thực hành nào bạn thích và tại sao.

Trong phần tiếp theo của loạt bài này, chúng tôi sẽ xây dựng một ứng dụng Công việc đơn giản và áp dụng một số các thực tiễn và mô hình tốt nhất này.

Bài viết này có hữu ích không? Vui lòng nhấp vào nút Clap bên dưới, hoặc theo dõi tôi để biết thêm.

Cảm ơn vì đã đọc! Nếu bạn có bất kỳ phản hồi, hãy để lại nhận xét bên dưới.

Chuyển đến Phần 7-b: Xây dựng ứng dụng ToDo đơn giản (Sớm)