简体   繁体   中英

React/Redux Handling Two-Way Data

I'm struggling to properly organize my Redux Store and my React components to properly deal with two-way nested data.

Suppose I have a post model and a user model. Let's take an abstracted example:

const user = {
    "id": "1",
    "name": "user 1",
    "posts": [...] // list of post objects
}

const post = {
    "id": "1",
    "title": "post 1",
    "user": user
}

The problem is that I cannot load this data like this because it will cause an infinite recursion error. I have to omit either the posts from the user or omit the user from the posts .

Here's what I ideally need:

I need to have a single post page that displays the post user with all his info (id, name) and the user's list of posts with the post info (id, title) in the same screen all at once.

I use normalizr to normalize the data.

How would I go about loading the data?

As per Redux docs ( https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape ) you should avoid nesting objects.

The solution here would be to treat the data like it is a database. That means that you should store ids instead of objects.

In your example:

const user = {
  "id": "1",
  "name": "user 1",
  "posts": ["1", "2", ...] // list of post objects IDs
}

const post = {
  "id": "1",
  "title": "post 1",
  "userId": "1"
}

Normally you would only save post_ids in the user, and user_id in the post. normalizer schemas can be configured to deal with those relations.

What is the incentive of adding the user key in post ? Having shared data within two related data structures is redundant. The only data you should have in post is the relevant data and the minimum amount of information you need to properly associate the user with his/her post s. I would imagine you would want to have the string name of the user in post , or an id number of the user inside each post object

const user = {
    "id": "1",
    "name": "user 1",
    "posts": [...] // list of post objects
}

const post = {
    "id": "1",
    "title": "post 1",
    "user": "user 1"
}

EDIT: From your comment, I would make an array of all users . But with a post key that is only the ids of posts that are associated with that user. And another array of only posts . As before, have an identifier to correlate the two. After that, parse your frontend on an as needed basis.

const users = [
  { name: 'andrew', id: 10, postIds: [1,3,23,30]},
  // ...more users
]

const posts = [
  { name: 'a post', id: 23, userId: 10 }
  { name: 'another post', id: 3, userId: 10 }
  { name: 'a third post', id: 2, userId: 3 }
  // ...more posts
]

Technically, userId is optional, but it can be a nice-to-have to be able to identify a user when inspecting individual posts

EDIT: Wow, I just scrolled down and saw nordus has the exact same proposal, before me. While it's nice to see we're on the same page, make sure he/she gets credit if you like the idea ;).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM