Trello Clone - phần 1 - Styled Components

Styled-Components là một thư viện giúp bạn tổ chức và quản lý styles trong các dự án sử dụng React tuân theo đề xuất từ Facebook.
Trello Clone - phần 1 - Styled Components
Trello Clone - phần 1 - Styled Components

Có nhiều cách thực hiện việc xây dựng layout cho các dự án sử dụng React.

  • Cách truyền thống: chúng ta import các files CSS qua các thẻ link. Hầu hết mọi người đều sử dụng cách này. Tuy nhiên, nếu bạn muốn đóng gói một số styles nào đó chỉ có thể được sử dụng riêng cho một số components thì hơi khó thực hiện nhé.
  • Style trực tiếp cho các components thông qua props style. Cách này cực kỳ gây rối và dễ nhầm lẫn cho codebase cũng như khó tái sử dụng.
import { Column } from './Column'
import { Card } from './Card'
import { AppContainerView } from '../styled/AppContainerView'
import React from 'react'

export const Example = () => {
  return (
    <AppContainerView className="app-container">
      <div style={{
        display: 'flex',
        flexFlow: 'column nowrap',
      }}>
        <Column text="To Do">
          <Card text="Write Post Everyday" />
          <Card text="Wake up at 6 AM" />
          <Card text="Go to work" />
        </Column>
      </div>
    </AppContainerView>
  )
}
  • Sử dụng các thư viện styling bên ngoài.

Để hạn chế các tác động không mong muốn lẫn nhau giữa các components và libraries, Facebook đề xuất styles của các components nên được đóng gói tách biệt và chỉ có tác dụng trong phạm vi component đó.

 

Styled Components

Styled-Components là một thư viện giúp bạn tổ chức và quản lý styles trong các dự án sử dụng React tuân theo đề xuất từ Facebook. Mục tiêu chủ yếu của nó là giữ styles của các components trong React gắn liền với chính các components đó. Styled-Components cung cấp một interface rõ ràng và dễ sử dụng cho cả React và React Native. Nó không chỉ thay đổi quá trình phát triển các components trong React mà còn thay đổi cả lối tư duy trong việc xây dựng styles cho các components đó.

Trello là một ứng dụng giúp chúng ta dễ dàng ghi chú cũng như lên kế hoạch thực hiện các công việc hằng ngày. Chắc hẳn các bạn ai cũng đều biết nó rồi đúng không? ^_^

Chúng ta hãy cùng nhau thử clone ứng dụng Trello này với React - TypeScriptStyled-Components nhé. 

trello-clone-demo.jpg

Hình demo thôi, không được như vậy đâu =)))

 

Khởi tạo ứng dụng

Để đơn giản, chúng ta hãy bắt đầu bằng create-react-app nhé.

# Sử dụng npx
npx create-react-app trello-clone --template typescript

# Hoặc máy bạn đã cài đặt yarn
yarn create react-app trello-clone --template typescript

cd trello-clone

Các đoạn hướng dẫn từ lúc này trở đi mình sẽ chỉ dùng yarn thôi nhé.

 

Cài đặt styled-components

yarn add styled-components

Chúng ta cũng cần cài đặt thêm bộ khai báo kiểu cho styled-components, nếu không, TypeScript sẽ báo lỗi.

yarn add @types/styled-components

 

Style cho AppContainer

Chúng ta cần một layout chứa danh sách các cột được sắp xếp theo chiều ngang. Ở đây mình sử dụng flexbox.

# src/styled/AppContainerView.tsx

import styled from 'styled-components'

export const AppContainerView = styled.div`
  align-items: flex-start;
  background-color: #3179ba;
  display: flex;
  flex-direction: row;
  height: 100vh;
  padding: 20px;
  width: 100%;
  overflow: auto;
`

Thử gọi nó trong App xem sao.

# src/App.tsx

import React from 'react'
import './App.css'
import { AppContainerView } from './styled/AppContainerView'

const App = () => {
  return (
    <AppContainerView>
      Columns will go here
    </AppContainerView>
  )
}

export default App

Chạy thử cái

yarn start

 

Xấu vl :)))

step-1.jpg

 

Chúng ta tiếp tục tạo thêm một số styled views như sau:

# src/styled/CardContainerView.tsx

import styled from 'styled-components'

export const CardContainerView = styled.div`
  background-color: #fff;
  cursor: pointer;
  margin-bottom: 0.5rem;
  padding: 0.5rem 1rem;
  max-width: 300px;
  border-radius: 3px;
  box-shadow: #091e4240 0 1px 0 0;
`
# src/styled/ColumnContainerView.tsx

import styled from 'styled-components'

export const ColumnContainerView = styled.div`
  background-color: #ebecf0;
  width: 300px;
  min-height: 40px;
  margin-right: 20px;
  border-radius: 3px;
  padding: 8px 8px;
  flex-grow: 0;
`
# src/styled/ColumnTitleView.tsx

import styled from 'styled-components'

export const ColumnTitleView = styled.div`
  padding: 6px 16px 12px;
  font-weight: bold;
`

 

Tạo ColumnCard

# src/components/Column.tsx

import { ColumnContainerView } from '../styled/ColumnContainerView'
import { ColumnTitleView } from '../styled/ColumnTitleView'
import React from 'react'

interface ColumnProps {
  text?: string
}

export const Column = ({
  text,
  children,
}: React.PropsWithChildren<ColumnProps>) => {
  return (
    <ColumnContainerView>
      <ColumnTitleView>{text}</ColumnTitleView>
      {children}
    </ColumnContainerView>
  )
}

Để render các children components bên trong Column, chúng ta cần xác định kiểu cho props truyền vào ColumnReact.PropsWithChildren.

# src/components/Card.tsx

import { CardContainerView } from '../styled/CardContainerView'

interface CardProps {
  text: string
}

export const Card = ({ text }: CardProps) => {
  return <CardContainerView>{text}</CardContainerView>
}

 

Giờ cập nhật lại file App.tsx rồi chạy thử nhé:

# src/App.tsx

import React from 'react'
import './App.css'
import { AppContainerView } from './styled/AppContainerView'
import { Column } from './components/Column'
import { Card } from './components/Card'

const App = () => {
  return (
    <AppContainerView>
      <Column text="To Do">
        <Card text="Write Post Everyday" />
        <Card text="Wake up at 6 AM" />
        <Card text="Go to work" />
      </Column>
      <Column text="In Progress">
        <Card text="Learn React" />
        <Card text="Learn Typescript" />
      </Column>
      <Column text="Done">
        <Card text="Have breakfast" />
      </Column>
    </AppContainerView>
  )
}

export default App

 

Và đây là kết quả:

step-2.jpg

Đỡ hơn rồi ha. Ờ mây zing gút chóp em :)))

amazing-good-job.jpg

 

Tạm kết thúc ở đây nhé các bạn.

Bài viết tới mình sẽ hướng dẫn các bạn các interactions với ứng dụng như: thêm - sửa - xóa Column cũng như Card.

Cám ơn các bạn đã theo dõi và ủng hộ.

Comments

Bài viết nổi bật

Dạo gần đây đi đâu cũng nghe nói về microservices, người người nhà nhà rục rịch chuyển dịch hệ thống sang microservices. Trước khi đưa ra sự so sánh, mình sẽ khái quát một chút về Monolith Application và MicroServices một chút cho các bạn chưa biết nắm rõ hơn nhé.
PHP là ngôn ngữ được sử dụng rộng rãi nhất trên thế giới trong lập trình web. Nó cũng bị ghét nhất. Nhưng tại sao nhiều developer lại ghét nó đến vậy? Hôm nay chúng ta hãy cùng tìm hiểu lý do xem chúng có thuyết phục không nhé ^_^
Lúc trước mình hay sử dụng cách này trên laptop phụ của mình, giờ mua license luôn rồi. Hôm nay mình xin chia sẻ cho bạn nào cần nhé.
JWT Tokens là một cách thức lưu trữ thông tin xác thực hiệu quả, nhưng làm cách nào để chúng ta có thể giúp chúng an toàn hơn? Có 2 cách thường dùng để lưu trữ JWT Tokens là LocalStorage và Cookies. Bây giờ chúng ta sẽ bắt đầu "mổ xẻ" các ưu - nhược điểm của mỗi loại nhé.
Có khá nhiều bạn đã yêu cầu mình một bài viết về Repository Design Pattern. Vậy mục đích của nó là gì? Nó có thực sự cần thiết cho ứng dụng của bạn hay không? Những điểm mạnh, điểm yếu của nó là gì? Chúng ta cùng đi sâu tìm hiểu qua bài viết này nhé.

Mục lục

Related posts

Triển khai Saga Pattern trong microservices với NodeJS và Choreography-Based Saga
Mô hình Saga đưa ra một giải pháp có cấu trúc để giải quyết thách thức này. Nó cung cấp một phương pháp có hệ thống để quản lý transaction qua nhiều microservices. Điều này giải quyết những phức tạp của các transaction phân tán và hoàn toàn tương thích với các nguyên tắc của kiến trúc microservices, được đặc trưng bởi sự kết nối lỏng lẻo và khả năng triển khai độc lập của các service.
Một API cho phép giao tiếp hai chiều giữa các ứng dụng phần mềm thông qua các requests. Một Webhook là một API nhẹ, hỗ trợ chia sẻ dữ liệu một chiều được kích hoạt bởi các events.
Một trong những câu hỏi được đặt thường xuyên nhất về TypeScript là liệu chúng ta nên sử dụng interface hay type. Câu trả lời cho câu hỏi này, giống như nhiều câu hỏi lập trình khác, là nó phụ thuộc vào tình hình cụ thể. Trong một số trường hợp, một cái có lợi thế rõ rệt hơn cái kia, nhưng trong nhiều trường hợp, chúng có thể thay thế cho nhau.
Đây là các types cơ bản nhưng cũng phổ biến nhất trong Typescript. Một số types khác phức tạp hơn cũng được xây dựng dựa trên những types cơ bản này.
Trong thế giới lập trình, trách nhiệm lớn nhất của chúng ta không phải chỉ làm cho code chạy được, mà còn phải đảm bảo rằng các đoạn code mà chúng ta viết có thể dễ dàng kiểm tra và bảo trì trong một khoảng thời gian dài.
Phân trang - một thành phần không thể thiếu trong các ứng dụng có lượng dữ liệu lớn. Tuy nhiên, bạn hiểu được bao nhiêu về nó?
Javascript là một thành phần không thể thiếu đối với frontend developers. Tuy nhiên, ngay từ lúc ra đời, nó đã tồn tại khá nhiều vấn đề cần khắc phục. Đó là lý do tại sao từ 2015 (ES6) tới 2021 (ES12) ra đời nhằm giúp Javascript trở nên tốt hơn.
Dạo này mình làm việc với mấy bạn trên github, thấy hay xài mấy từ viết tắt mà mình không hiểu lắm. Thôi thì tổng hợp lại một list các từ viết tắt hay dùng trong github luôn cho ai cần :D
Dạo gần đây đi đâu cũng nghe nói về microservices, người người nhà nhà rục rịch chuyển dịch hệ thống sang microservices. Trước khi đưa ra sự so sánh, mình sẽ khái quát một chút về Monolith Application và MicroServices một chút cho các bạn chưa biết nắm rõ hơn nhé.
Cách bỏ qua câu lệnh --set-upstream quen thuộc cho các con lười
Mình sẽ giới thiệu 2 cách để xóa một property trong Javascript Object. Một cách sử dụng mutable - toán tử delete, một cách còn lại là immutable - tính năng Object Restructuring.

Tin mới nhất

Triển khai Saga Pattern trong microservices với NodeJS và Choreography-Based Saga
Mô hình Saga đưa ra một giải pháp có cấu trúc để giải quyết thách thức này. Nó cung cấp một phương pháp có hệ thống để quản lý transaction qua nhiều microservices. Điều này giải quyết những phức tạp của các transaction phân tán và hoàn toàn tương thích với các nguyên tắc của kiến trúc microservices, được đặc trưng bởi sự kết nối lỏng lẻo và khả năng triển khai độc lập của các service.
Một API cho phép giao tiếp hai chiều giữa các ứng dụng phần mềm thông qua các requests. Một Webhook là một API nhẹ, hỗ trợ chia sẻ dữ liệu một chiều được kích hoạt bởi các events.
Một trong những câu hỏi được đặt thường xuyên nhất về TypeScript là liệu chúng ta nên sử dụng interface hay type. Câu trả lời cho câu hỏi này, giống như nhiều câu hỏi lập trình khác, là nó phụ thuộc vào tình hình cụ thể. Trong một số trường hợp, một cái có lợi thế rõ rệt hơn cái kia, nhưng trong nhiều trường hợp, chúng có thể thay thế cho nhau.
Trong phần này, chúng ta sẽ tìm hiểu một số khái niệm cơ bản nhất về AWS là gì và một số lợi ích khi sử dụng AWS.
Trở thành một software developer hiệu suất cao không phải là điều dễ dàng. Điều này đòi hỏi bạn phải có kỹ năng và kiến thức về lập trình, cũng như cách tiếp cận và giải quyết các vấn đề phức tạp. Tuy nhiên, nếu bạn có chút kiên nhẫn và sự nỗ lực, bạn hoàn toàn có thể trở thành một developer tài năng và thành công.
Đây là các types cơ bản nhưng cũng phổ biến nhất trong Typescript. Một số types khác phức tạp hơn cũng được xây dựng dựa trên những types cơ bản này.
Trong thế giới lập trình, trách nhiệm lớn nhất của chúng ta không phải chỉ làm cho code chạy được, mà còn phải đảm bảo rằng các đoạn code mà chúng ta viết có thể dễ dàng kiểm tra và bảo trì trong một khoảng thời gian dài.
Thông tin được định nghĩa dưới dạng dữ liệu, kiến thức về thông tin, và trí tuệ về tri thức.
Phân trang - một thành phần không thể thiếu trong các ứng dụng có lượng dữ liệu lớn. Tuy nhiên, bạn hiểu được bao nhiêu về nó?
Javascript là một thành phần không thể thiếu đối với frontend developers. Tuy nhiên, ngay từ lúc ra đời, nó đã tồn tại khá nhiều vấn đề cần khắc phục. Đó là lý do tại sao từ 2015 (ES6) tới 2021 (ES12) ra đời nhằm giúp Javascript trở nên tốt hơn.
Dạo này mình làm việc với mấy bạn trên github, thấy hay xài mấy từ viết tắt mà mình không hiểu lắm. Thôi thì tổng hợp lại một list các từ viết tắt hay dùng trong github luôn cho ai cần :D
Triển khai Saga Pattern trong microservices với NodeJS và Choreography-Based Saga
Mô hình Saga đưa ra một giải pháp có cấu trúc để giải quyết thách thức này. Nó cung cấp một phương pháp có hệ thống để quản lý transaction qua nhiều microservices. Điều này giải quyết những phức tạp của các transaction phân tán và hoàn toàn tương thích với các nguyên tắc của kiến trúc microservices, được đặc trưng bởi sự kết nối lỏng lẻo và khả năng triển khai độc lập của các service.
Một API cho phép giao tiếp hai chiều giữa các ứng dụng phần mềm thông qua các requests. Một Webhook là một API nhẹ, hỗ trợ chia sẻ dữ liệu một chiều được kích hoạt bởi các events.
Một trong những câu hỏi được đặt thường xuyên nhất về TypeScript là liệu chúng ta nên sử dụng interface hay type. Câu trả lời cho câu hỏi này, giống như nhiều câu hỏi lập trình khác, là nó phụ thuộc vào tình hình cụ thể. Trong một số trường hợp, một cái có lợi thế rõ rệt hơn cái kia, nhưng trong nhiều trường hợp, chúng có thể thay thế cho nhau.
Đây là các types cơ bản nhưng cũng phổ biến nhất trong Typescript. Một số types khác phức tạp hơn cũng được xây dựng dựa trên những types cơ bản này.