Cách đồng bộ trạng thái Redux và thông số thẻ băm url


76

Chúng tôi có một danh sách các bài giảng và chương để người dùng có thể chọn và bỏ chọn chúng. Hai danh sách được lưu trữ trong một cửa hàng redux. Bây giờ chúng tôi muốn giữ một bản đại diện của các sên bài giảng và sên chương đã chọn trong thẻ băm của url và bất kỳ thay đổi nào đối với url cũng nên thay đổi cửa hàng (đồng bộ hai chiều).

Giải pháp tốt nhất sử dụng react-router hoặc thậm chí react-router-redux sẽ là gì?

Chúng tôi thực sự không thể tìm thấy một số ví dụ tốt trong đó bộ định tuyến phản ứng chỉ được sử dụng để duy trì thẻ băm của một url và cũng chỉ cập nhật một thành phần.


4
Tại sao bạn muốn giữ trạng thái này trong cửa hàng, thay vì chỉ sử dụng Bộ định tuyến React làm nguồn trung thực cho các tham số URL và sử dụng các đạo cụ mà nó đưa vào mapStateToProps của bạn (trạng thái, ownProps)?
Dan Abramov

2
Bởi vì các tham số url chỉ chứa các slugs của bài giảng và các chương được chọn. Trong cửa hàng, tôi có một danh sách các bài giảng và chương với tên, slug và giá trị Boolean đã chọn.
JoKer

1
ví dụ: sử dụng peterbeshai.com/react-url-query ?
mb21

Câu trả lời:


149

Tôi nghĩ bạn không cần phải làm vậy.
(Xin lỗi vì một câu trả lời phiến diện nhưng đó là giải pháp tốt nhất theo kinh nghiệm của tôi.)

Lưu trữ là nguồn trung thực cho dữ liệu của bạn. Điều này là tốt.
Nếu bạn sử dụng React Router, hãy để nó là nguồn trung thực cho trạng thái URL của bạn.
Bạn không cần phải giữ mọi thứ trong cửa hàng.

Ví dụ: xem xét trường hợp sử dụng của bạn:

Bởi vì các tham số url chỉ chứa các slugs của bài giảng và các chương được chọn. Trong cửa hàng, tôi có một danh sách các bài giảng và chương với tên, slug và giá trị Boolean đã chọn.

Vấn đề là bạn đang sao chép dữ liệu. Dữ liệu trong store ( chapter.selected) được sao chép ở trạng thái React Router. Một giải pháp sẽ là đồng bộ hóa chúng, nhưng điều này nhanh chóng trở nên phức tạp. Tại sao không để React Router là nguồn chân lý cho các chương đã chọn?

Trạng thái cửa hàng của bạn sau đó sẽ trông giống như (đơn giản hóa):

{
  // Might be paginated, kept inside a "book", etc:
  visibleChapterSlugs: ['intro', 'wow', 'ending'],

  // A simple ID dictionary:
  chaptersBySlug: {
    'intro': {
      slug: 'intro',
      title: 'Introduction'
    },
    'wow': {
      slug: 'wow',
      title: 'All the things'
    },
    'ending': {
      slug: 'ending',
      title: 'The End!'
    }
  }
}

Đó là nó! Đừng lưu trữ selectedở đó. Thay vào đó, hãy để React Router xử lý nó. Trong trình xử lý tuyến đường của bạn, hãy viết một cái gì đó như

function ChapterList({ chapters }) {
  return (
    <div>
      {chapters.map(chapter => <Chapter chapter={chapter} key={chapter.slug} />)}
    </div>
  )
}

const mapStateToProps = (state, ownProps) => {
  // Use props injected by React Router:
  const selectedSlugs = ownProps.params.selectedSlugs.split(';')

  // Use both state and this information to generate final props:
  const chapters = state.visibleChapterSlugs.map(slug => {
    return Object.assign({
      isSelected: selectedSlugs.indexOf(slug) > -1,
    }, state.chaptersBySlug[slug])
  })

  return { chapters }
}

export default connect(mapStateToProps)(ChapterList)

4
xin lỗi vì đã về muộn nhưng tuần trước tôi được nghỉ. Tôi có một câu hỏi. Bạn đã mô tả một cách lấy dữ liệu từ url và hiển thị nó. Bạn sẽ cập nhật url với các chương mới được chọn như thế nào?
JoKer

9
Tôi sẽ gọi browserHistory.push()( browserHistoryđược nhập từ đâu react-router) trong trình tạo hành động. Tôi có thể sẽ sử dụng Redux Thunk để làm rõ rằng có một tác dụng phụ đang xảy ra. Tôi sẽ gọi dispatch({ ... }); browserHistory.push(...)vào bên trong nó.
Dan Abramov

2
Này Dan. Cảm ơn vì Redux! Của tôi Tôi cũng đặt 2 xu của tôi vào chủ đề và đặt một câu hỏi. Điều gì sẽ xảy ra nếu một logic chuyển đổi trạng thái ứng dụng phụ thuộc vào dữ liệu trong một truy vấn? Điều đó có nghĩa là bộ giảm giá cần nó và bạn không thể bỏ nó trong cửa hàng.
Alexander Reshytko

2
@AlexanderReshytko Vì dữ liệu này đến từ “thế giới bên ngoài” nên tôi sẽ thực hiện các hành động với nó khi cần thiết . Điều này không có nghĩa là bạn cần một hành động chung chung "đã thay đổi tuyến đường" (mặc dù bạn có thể thực hiện nó nếu bạn thấy nó hữu ích). Sau đó, bộ giảm bớt của bạn có thể sử dụng thông tin đó, giống như cách họ thường làm.
Dan Abramov

8
Hơi khó xử khi gửi các tham số đến các bộ chọn chọn lại, vì vậy việc có thể lấy các tham số url hiện tại từ cửa hàng là rất hữu ích.
Jacob Rask

3

react-router-redux có thể giúp bạn nhập nội dung url để lưu trữ, vì vậy mỗi khi thẻ băm thay đổi, hãy lưu trữ luôn.


23
Nó chỉ cung cấp cho bạn vị trí chứ không phải các tham số được phân tích cú pháp, vì vậy nó có giới hạn hữu ích trừ khi bạn hoàn thành tốt những gì React Router cung cấp cho bạn theo cách thủ công. Đó là một giải pháp tốt để giữ cho cửa hàng đồng bộ với các hành động để ghi và phát lại các phiên người dùng hoạt động nhưng nó không thực sự hữu ích cho các ứng dụng không cần điều này.
Dan Abramov
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.