【问题标题】:How to migrate app state from React Context to Redux Tool Kit?如何将应用程序状态从 React Context 迁移到 Redux Tool Kit?
【发布时间】:2021-09-23 18:33:12
【问题描述】:

我想要达到的目标:

我有一个 NextJS + Shopify 店面 API 应用程序。最初,我为状态管理设置了一个 Context api,但效率不高,因为它会重新渲染包含在其中的所有内容。因此,我将所有状态转移到 Redux Toolkit。

Redux 逻辑非常复杂,我还不知道所有的陷阱。但到目前为止,我遇到了几个问题。例如,在我的旧 Context API 结构中,我有 couple functions 接受 couple arguments

    const removeFromCheckout = async (checkoutId, lineItemIdsToRemove) => {
        client.checkout.removeLineItems(checkoutId, lineItemIdsToRemove).then((checkout) => {
            setCheckout(checkout);
            localStorage.setItem('checkout', checkoutId);
        });
    }

    const updateLineItem = async (item, quantity) => {
        const checkoutId = checkout.id;
        const lineItemsToUpdate = [
            {id: item.id, quantity: parseInt(quantity, 10)}
        ];
        client.checkout.updateLineItems(checkoutId, lineItemsToUpdate).then((checkout) => {
            setCheckout(checkout);
        });
    }

来自状态的一个参数 (checkoutId) 和另一个通过 map() 方法提取的参数 (lineItemIdsToRemove)。 在 JSX 中的实际组件内部,它看起来和唤起如下:

<motion.button 
    className="underline cursor-pointer font-extralight"
    onClick={() => {removeFromCheckout(checkout.id, item.id)}}
>

如何在 createSlice({ }) 中声明这种类型的函数? 因为 createSlice 中的 reducers 唯一可以接受的参数类型是 (state, action)还有可能在一个文件中有多个 useSelector() 调用吗?

我有两个不同的“切片”文件导入到组件中:

    const {toggle} = useSelector((state) => state.toggle);
    const {checkout} = useSelector((state) => state.checkout);

只有 {checkout} 给了我这个错误: TypeError: Cannot destructure property 'checkout' of 'Object(...)(...)' as it is undefined.

感谢您的关注,希望有人能对此有所了解。

【问题讨论】:

    标签: reactjs redux react-redux react-context redux-toolkit


    【解决方案1】:

    您可以为此使用prepare notation

    const todosSlice = createSlice({
      name: 'todos',
      initialState: [] as Item[],
      reducers: {
        addTodo: {
          reducer: (state, action: PayloadAction<Item>) => {
            state.push(action.payload)
          },
          prepare: (id: number, text: string) => {
            return { payload: { id, text } }
          },
        },
      },
    })
    
    dispatch(todosSlice.actions.addTodo(5, "test"))
    

    但在 99% 的情况下,您可能会继续使用单参数表示法,只是将对象作为有效负载传递,例如

    dispatch(todosSlice.actions.addTodo({ id: 5, text: "test"}))
    

    因为它只是在没有准备符号的情况下开箱即用,并且无论如何都会使您的代码更具可读性。

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 2021-04-15
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 2019-11-26
      • 2022-11-28
      • 1970-01-01
      相关资源
      最近更新 更多