reactjs 由一个组件引入的Redux状态更改不会反映在使用useSelector挂钩的其他组件上

bf1o4zei  于 2022-11-29  发布在  React
关注(0)|答案(1)|浏览(117)

从那以后,我修改了我的代码,把重点放在这个问题上,这样无论谁试图提供帮助,它都更容易理解。

方案

我有一个用Redux工具包创建的redux存储,它有一个名为“asts”的切片,并用“astsTestData”数组初始化。

import { createSlice } from "@reduxjs/toolkit";
import { astsData, astsTestData } from "../data/astsData/astsData";

const astsSlice = createSlice({
    name: "asts",
    initialState: { astsData, astsTestData },
    reducers: {
        astCreated: (state, action) => {
            state.astsData.push(action.payload);
        },
        astUpdated: (state, action) => {},
        astDeleted: (state, action) => {},
        astTestDataCreated: (state, action) => {
            console.log(`astTestDataCreated running`);
            console.log(`state.astsTestData`, state.astsTestData);
            console.log(`action`, action);
            return {
                ...state,
                astsTestData: [...astsTestData, action.payload],
            };

            // state.astsTestData.push(action.payload)
        },
    },
});

// console.log(`astsSlice`, astsSlice)

export const { astCreated, astUpdated, astDeleted, astTestDataCreated } =
    astsSlice.actions;

export default astsSlice.reducer;

我有另一个名为“sch”的切片,这个切片存储rgv数据。

import { createSlice } from "@reduxjs/toolkit";
import { poData, splData, grvData } from "../data/schData/schData";

const schSlice = createSlice({
    name: "sch",
    initialState: { poData, splData, grvData },
    reducers: {
        // Purchase Order reducers
        // Goods receiving reducers
        grvCreated: (state, action) => {
            console.log(`grvCreated running`);
            console.log(`state.grvData`, state.grvData);
            console.log(`action`, action);
            state.grvData.push(action.payload);
        },
        grvUpdated: (state, action) => {},
        grvDeleted: (state, action) => {},
    },
});

// console.log(`schSlice`, schSlice);

export const {
    poCreated,
    poUpdated,
    poDeleted,
    popCreated,
    popUpdated,
    popDeleted,
    grvCreated,
    grvUpdated,
    grvDeleted,
} = schSlice.actions;

export default schSlice.reducer;

我有一个名为“Sch”的React组件,它在一个ag-grid表上显示“sch.grvData”。“Sch在一个名为”GrvTestTable“的组件上使用”ag-grid“来显示使用useSelctor获得的”sch.rgvData“。这部分一直工作得很好。

import React from "react";
import GrvTestAddAstBtn from "../../components/forms/grvForm/grvTest/GrvTestAddAstBtn";
import GrvTestTable from "../../components/forms/grvForm/grvTest/GrvTestTable";

const Sch = () => {
    return (
        <div className="sch">
            <GrvTestTable /> 
            <GrvTestAddAstBtn /> 
        </div>
    );
};
export default Sch;

该表显示通过从grv表单上的“handlSubmit”分派而创建的“sch.grvData”记录。

const handleSubmit = e => {
        e.preventDefault();;
        // dispatch data to 'sch.grvData'
        dispatch(grvCreated(grvFormData));
        // dispatch data to 'asts.astsTestData'
        dispatch(
            astTestDataCreated({
                astId: nanoid(),
                grvId: grvFormData.grvId,
                astCartegory: grvFormData.grvAstCartegory,
                astNo: grvFormData.grvAstNo,
            })
        );
        setModalOpened(false);
        setGrvFormData([]);
        setComponentToOpen("");
    };

在“Schs”中,除了ag网格表之外,还有一个用于打开“grv表单”的按钮,在提交时,grv表单数据被写入redux存储中的“sch.rgvData”,之后,相同的数据被用于在“asts. astsTestData”上创建新的asts记录。
我有另一个名为“TestAstTable”的组件,它使用ag数据网格表显示“asts.astsTestData”。这就是问题所在。
ag-grid表(和)都通过useSelector从网格存储中接收数据。

测试资产表

import React, { useRef, useMemo, useState, useEffect } from "react";
import { AgGridReact } from "ag-grid-react"; // the AG Grid React Component

import "ag-grid-community/styles/ag-grid.css"; // Core grid CSS, always needed
import "ag-grid-community/styles/ag-theme-alpine.css"; // Optional theme CSS

import "react-tippy/dist/tippy.css";
import { useSelector, useStore } from "react-redux";

const TestAstsTable = () => {

  const { astsTestData } = useSelector(state => state.asts)
    console.log(`astsTestData`, astsTestData);
  
  const [rowData, setRowData] = useState(astsTestData)

  const [columnDefs] = useState([
    { field: "astId" },
    { field: "grvId" },
    { field: "astCartegory" },
    { field: "astNo"},
  ])

    useEffect(() => {
        setRowData(astsTestData);
    }, [astsTestData]);
    

    const gridRef = useRef(); 
    const defaultColDef = useMemo(
        () => ({
            sortable: true,
            filter: true,
            resizable: true,
        }),
        []
    );

    // console.log(`rowData`, rowData);

    return (
        <div className={`ag-theme-alpine `}>
            <AgGridReact
                ref={gridRef} // Ref for accessing Grid's API
                rowData={rowData} // Row Data for Rows
                columnDefs={columnDefs} // Column Defs for Columns
                defaultColDef={defaultColDef} // Default Column Properties
                animateRows={true} // Optional - set to 'true' to have rows animate when sorted
                rowSelection="single" // Options - allows click selection of rows
                domLayout={"autoHeight"}
            />
        </div>
    );
};

export default TestAstsTable;

// TODO: mouse over tips on the TestAstsTable skipHeader

Grv测试表

import React, { useRef, useMemo, useState, useEffect } from "react";
import { AgGridReact } from "ag-grid-react"; // the AG Grid React Component

import "ag-grid-community/styles/ag-grid.css"; // Core grid CSS, always needed
import "ag-grid-community/styles/ag-theme-alpine.css"; // Optional theme CSS

import "react-tippy/dist/tippy.css";
import { useSelector } from "react-redux";

const GrvTestTable = () => {
    const { grvData } = useSelector(state => state.sch);
    console.log(`grvData`, grvData);

    const [rowData, setRowData] = useState(grvData);

    useEffect(() => {
        setRowData(grvData)
    }, [grvData]);

    const [columnDefs] = useState([
        { field: "grvId" },
        { field: "grvAstCartegory" },
        { field: "grvAstNo" },
    ]);

    const gridRef = useRef();
    const defaultColDef = useMemo(
        () => ({
            sortable: true,
            filter: true,
            resizable: true,
        }),
        []
    );

    // console.log(`rowData`, rowData);

    return (
        <div className={`ag-theme-alpine `}>
            <AgGridReact
                ref={gridRef} // Ref for accessing Grid's API
                rowData={rowData} // Row Data for Rows
                columnDefs={columnDefs} // Column Defs for Columns
                defaultColDef={defaultColDef} // Default Column Properties
                animateRows={true} // Optional - set to 'true' to have rows animate when sorted
                rowSelection="single" // Options - allows click selection of rows
                domLayout={"autoHeight"}
            />
        </div>
    );
};

export default GrvTestTable;

每次在“sch. grvData”上创建新的“grv记录”时,都会在“asts. astsTestData”上创建一条ast记录。这是在“grv form”的表单提交处理程序(handleSubmit)上完成的。
通过redux devtools,我可以确认在从表单submit分派操作负载后存储得到了更新。通过redux dev tools,我可以看到'sch.rgvData'和'asts.astsTestData'都得到了更新。
使用redux工具包immer,我可以在我的reducer中对“sch.rgvData”(状态.grvData.push(动作.有效负载))和“asts.astsTestData”(状态.astsTestData.push(动作.有效负载))使用数组推送来更新不可变状态。

问题

TestAstTable”表组件使用useSelctor获取redux状态。astsTestData不会更新,但“GrvTestTable”会在每次提交grv表单时更新。
"我为解决问题所做的努力"
1.我在网上找遍了也没找到
1.我已经尝试过在astsTestData更新时使用useState和useEffect来触发重新渲染,但这不起作用。
1.我已经看过了,看看我是否没有改变商店,我没有
1.我想问题可能是不变性,所以我试着在化简器上用老方法,用immer,没有运气。用immer,我把acton有效载荷推到数组上。用老方法,我用对象传播算子。没有运气。
1.我已验证我只使用一个存储
"一些奇怪的观察“
当我使用redux dev工具查看'asts' redux页面时,我在redux存储中看不到更新的asts状态,但当我使用redux dev工具查看'Sch' redux页面时,我在redux存储中看到'sch.grvData'和'asts.astsTestData'更新的状态。这让我非常困惑。

gmol1639

gmol16391#

如果没有stackblitz等中可重现的示例,很难帮助您解决问题。

相关问题