简体   繁体   中英

How do I shift a prop array on Svelte?

I'm trying to build a post list, and posts are passed down to my component as a prop array. The thing is: I need it to have second and later posts, as the first is shown by another component.

I'm trying to run an array.splice() but as I don't know much about how reactivity is build on Svelte, all ways I've tried or had broke everything or had no effect.

Here's the component, where posts is the array I'm talking about:

<script>
import AppBlogPost from "./PostCards/AppBlogPost.svelte";

export let posts;
</script>

<style lang="scss">
</style>

<ul>
  {#each posts as post}
    <AppBlogPost {post} />
  {/each}
</ul>

To skip the first element in an array you can simply use array destructuring:

let [, ...arr2] = arr

This will take your arr and write the first element nowhere (the empty space) while writing all the rest to arr2 using the spread operator.

In the case of Svelte you probably want your post array still be reactive, so you have the mark assignment as such using $

<script>
import AppBlogPost from "./PostCards/AppBlogPost.svelte";

export let posts;
$: [, ...otherPosts] = posts
</script>

<ul>
  {#each otherPosts as post}
    <AppBlogPost {post} />
  {/each}
</ul>

This also opens up a new possibility, I guess you are using posts[0] to display the first post differently ? If you change the reactive statement to $: [firstPost, ...otherPosts] = posts you have it in a handy variable instead!

If members of your posts array changes, it won't be seen by svelte. You have to assign values as new to your posts array, then svelte will see the array has been changed.

const remove=()=>{
  posts.splice(0,1)
  posts=[...posts]
}

Svelte detects where re-renders are needed by checking for assignment using the = operator, not mutation. For example:

// no change detected
const obj = { foo: 1 }
obj.bar = 2

// change detected
let obj = { foo: 1 }
obj = { ...obj, bar: 2 }

As for Array#splice , it:

changes the contents of an array by removing or replacing existing elements and/or adding new elements in place .

That "in place" means it mutates the array and returns the deleted items.

If you're familiar with the splice API and want to use that, you could build an immutable version on top of it:

const spliceImmutable = arr => (...args) => {
    const clone = [...arr]
    clone.splice(...args)

    return clone
}

let arr = [0, 1, 2, 3, 4]
arr = spliceImmutable(arr)(2, 1, null) // [0, 1, null, 3, 4]

Or use custom logic based on Array#slice instead (more readable in my opinion):

let arr = [0, 1, 2, 3, 4]
arr = [ ...arr.slice(0, 2), null, ...arr.slice(3) ] // [0, 1, null, 3, 4]

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