0

I have created a store in svelte like:

const initalStore: FileDetailsPayload  = {
        jobID: 0,
        jobName: "",
        lastUploadInfo: {
          status: "",
          rowDetails: [],
          uploadTableData: {
             columns: [],
             data: []
          }
};


function CreateStore() {
    const { subscribe, set, update } = writable(initalStore);

    return {
        subscribe,
        set: (fileDetailList) => set(fileDetailList),
    };
}

export const fileDetailStore = CreateStore();

Now I am calling an API to set the store value, and I have subscribed the store in my component A.

const unsubscribe = fileDetailStore.subscribe((value) => {
        fileDetailsData = {...value};
    });

I am using the fileDetailsData in a child component Table which I am calling from Component A.

<Table tableData={fileDetailsData.uploadTableData} />

Issue: Whenever I am setting the new data in the store the store is getting updated and can see the updated value of store inside component A, But the child component which is Table is not getting re-rendered when the prop is changing. So overall I want my child component to get re-rendered on any change in props

Solution The problem was in the child component Table, where the local variables were not made reactive to the props.

Earlier: Table Component

<script>
export let tableData: TableData = { columns: [], data: [] };

    let columnData = tableData.columns || [];
    let rowData = tableData.data || [];
    let rowDataCopy = rowData.slice();
</script>
<div>
// using columnData and rowDataCopy
</div>

Now: Table Component

<script>
    export let tableData: TableData = { columns: [], data: [] };
    
    $: columnData = tableData.columns || [];
    $: rowData = tableData.data || [];
    $: rowDataCopy = rowData.slice();
    </script>
    <div>
    // using columnData and rowDataCopy
    </div>
4
  • You generally don't need subscribe in components, just use $store to access the value. Commented Jun 30, 2023 at 11:59
  • 2
    Show the code of Table, it might not be using the property tableData correctly (losing reactivity). Commented Jun 30, 2023 at 12:02
  • This has been resolved, the issue was with the reactivity of the variables used in Child Component. Thanks for the hunch. Commented Jul 3, 2023 at 9:28
  • Please either add the code causing the issue to the question, post an answer explaining the problem & accept it, or delete the question. Commented Jul 3, 2023 at 9:33

1 Answer 1

0

This is not problem with svelte, it's that reference for uploadTableData is not changing, understand when you are doing {...value} you are changing the root reference but not the inner reference.

You need to deep clone the whole object of filedetails -

Use structuredClone or hack it by stringifying and parsing

structuredClone

  const unsubscribe = fileDetailStore.subscribe((value) => {
        fileDetailsData = structuredClone(value);
    });

or

  const unsubscribe = fileDetailStore.subscribe((value) => {
                fileDetailsData = JSON.parse(JSON.stringify(value))
            });
Sign up to request clarification or add additional context in comments.

1 Comment

I tried the above 2 suggestions but the issue still persist which is my child component <Table/> is not getting re-rendered and hence the table values are not changing. Earlier also, I was getting the updated store value in fileDetailsData . Any possible reason why <Table/> is not getting re-rendered when fileDetailsData is updating?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.