Bởi dnulib.edu.vn
Bạn đã bao giờ gặp khó khăn khi tìm kiếm mã nguồn, kho lưu trữ, người dùng, vấn đề hoặc yêu cầu pull trong các dự án phần mềm của mình? Đôi khi, việc này có thể trở nên rối rắm và mất thời gian. Nhưng đừng lo lắng, tôi sẽ giới thiệu cho bạn một cách để tìm kiếm một cách dễ dàng và nhanh chóng.
Reducer
Trước tiên, chúng ta sẽ tìm hiểu về “reducer”. Reducer định nghĩa cách trạng thái của ứng dụng thay đổi khi nhận các hoạt động từ kho lưu trữ. Tuy nhiên, nó chỉ mô tả những điều xảy ra, không mô tả cách thay đổi trạng thái.
Thiết kế State shape
Trong Redux, tất cả trạng thái của ứng dụng được lưu trữ dưới dạng một đối tượng duy nhất. Trước khi viết mã, chúng ta cần xác định các đối tượng cần thiết để biểu diễn trạng thái của ứng dụng.
Với ứng dụng “todo app” ví dụ, chúng ta cần lưu trữ hai thứ sau:
- Bộ lọc hiện tại.
- Danh sách các công việc thực tế.
Bạn sẽ thường thấy rằng bạn cần lưu trữ dữ liệu và trạng thái UI trong cây trạng thái. Tuy nhiên, hãy cố gắng giữ cho dữ liệu tách biệt với trạng thái của UI.
Lưu ý cho Các mối quan hệ
[updating]
Xử lý hoạt động
Bây giờ, sau khi đã xác định được đối tượng trạng thái, chúng ta sẽ bắt đầu viết reducer cho nó. Reducer là một hàm thuần túy (pure function) nhận trạng thái trước đó và hoạt động làm đầu vào và trả về trạng thái tiếp theo.
Nó được gọi là reducer vì đó là loại hàm bạn cần chuyển đến.
Ví dụ:
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
default:
return state
}
}
Một số điều bạn không bao giờ được làm trong reducer:
- Thay đổi tham số của nó.
- Gọi API hoặc chuyển đổi route.
- Gọi các hàm không thuần túy như Date.now(), Math.random().
Store
Trong phần trước, chúng ta đã định nghĩa các hoạt động mô tả những gì sẽ xảy ra và reducers để cập nhật trạng thái dựa trên các hoạt động đó.
Store là một đối tượng tổ hợp các hoạt động và reducers. Store có các nhiệm vụ sau:
- Lưu trạng thái của ứng dụng.
- Cho phép truy cập vào trạng thái thông qua hàm getState();
- Cho phép cập nhật trạng thái thông qua hàm dispatch(action).
- Đăng ký lắng nghe sự kiện thông qua hàm subscrible(listener).
- Xử lý hủy đăng ký lắng nghe sự kiện thông qua kết quả trả về của hàm subscible(listener).
Điều quan trọng là chỉ có một Store duy nhất trong ứng dụng với Redux. Khi bạn muốn tách hay phân chia logic xử lý dữ liệu, bạn sẽ sử dụng reducer composition thay cho nhiều store.
Việc tạo store rất dễ dàng nếu chúng ta đã có reducer. Trong phần trước, chúng ta đã sử dụng hàm combineReducers() để kết hợp nhiều reducer thành một. Bây giờ, hãy import nó và truyền vào hàm createStore.
Bạn có thể tùy chọn trạng thái khởi tạo khác như một tham số thứ hai cho createStore.
Gửi Hoạt động
Bây giờ, chúng ta đã hoàn thành việc tạo store.
Luồng dữ liệu
Kiến trúc của Redux xoay quanh luồng dữ liệu một chiều chặt chẽ. Điều này có nghĩa là tất cả dữ liệu trong ứng dụng tuân theo cùng một mô hình vòng đời, làm cho logic ứng dụng của bạn dễ dự đoán và dễ hiểu hơn.
Lifecycle dữ liệu của bất kỳ ứng dụng sử dụng Redux nào phải tuân theo 4 bước sau:
- Gọi store.dispatch(action) với action là một đối tượng đơn giản mô tả những gì đã xảy ra.
- Redux store gọi reducer mà bạn đã khai báo.
- Root reducer có thể kết hợp nhiều reducer kết quả thành một cây trạng thái duy nhất.
- Redux store lưu trữ cây trạng thái hoàn chỉnh trả về bởi root reducer.
Các thành phần hiển thị và container
Để sử dụng connect
, bạn cần xác định một hàm đặc biệt được gọi là mapStateToProps
. Hàm này sẽ chuyển đổi trạng thái hiện tại của Redux store thành các thuộc tính bạn muốn sử dụng cho thành phần hiển thị. Ví dụ, nếu VisibleTodoList
cần tính toán todos
để truyền cho TodoList
, chúng ta sẽ định nghĩa một hàm filter state.todos
dựa trên state.visibilityFilter
, và sử dụng nó trong mapStateToProps
.
Ngoài việc đọc trạng thái, các thành phần container cũng có thể gửi các hoạt động. Tương tự như trên, bạn có thể định nghĩa thêm một hàm gọi là mapDispatchToProps()
, nó sẽ nhận phương thức dispatch()
và trả về các thuộc tính bạn muốn thêm vào các thành phần hiển thị. Ví dụ, nếu chúng ta muốn VisibleTodoList
truyền một thuộc tính được gọi là onTodoClick
cho thành phần TodoList
, và chúng ta muốn onTodoClick
gửi các hoạt động TOGGLE_TODO
:
const mapDispatchToProps = dispatch => ({
onTodoClick: id => {
dispatch(toggleTodo(id))
}
})
Cuối cùng, chúng ta tạo VisibleTodoList
bằng cách gọi connect()
và truyền hai hàm này:
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Tham khảo: useyourloaf.com