英文:
redux-actions library to refactor a counter example in Typescript errors
问题
I am new to Typescript
and wanted to practice a library called redux-actions
. I followed this tutorial:
https://youtube.com/watch?v=8DH7Ekp2PWI&feature=shares
and I tried to use the redux-actions
tutorial
https://redux-actions.js.org/introduction/tutorial
but it does not work in jsfiddle or codepen, like they suggest, so I thought a better approach would be to modify the Youtube tutorial and use the redux-actions
library in the codebase from the YouTube video.
The codebase for the Youtube tutorial is on github.
https://github.com/Jon-Peppinck/react-redux-ts
However, I am having trouble with the actions and reducer components. Here is what I have tried
Counter.ts
export interface Counter {
count: number;
}
CounterActions.ts
import { createActions } from "redux-actions";
export const { increment, decrement } = createActions({
INCREMENT: (amount = 1) => ({ amount }),
DECREMENT: (amount = 1) => ({ amount: -amount }),
});
interface IncrementAction {
type: typeof increment;
}
interface DecrementAction {
type: typeof decrement;
}
export type CounterActionTypes = IncrementAction | DecrementAction;
CounterReducer.ts
import { handleActions } from "redux-actions";
import { CounterActionTypes, decrement, increment } from "./CounterAction";
import { Counter } from "./models/Counter";
const defaultState: Counter = {
count: 0,
};
export const counterReducer = handleActions(
{
[increment]: (state: Counter, { payload: { amount } }: any): Counter => {
return { ...state, count: state.count + amount };
},
[decrement]: (state: Counter, { payload: { amount } }: any): Counter => {
return { ...state, count: state.count + amount };
},
},
defaultState
);
But the increment and decrement actions are showing an error:
A computed property name must be of type 'string', 'number', 'symbol', or 'any'.ts(2464)
I am also not sure of the way I have typed the payload
using any
, is there a better way to type it. How can I fix my code and prevent the errors? Also, are there any resources or tutorials on using redux-actions that are not paid content. I searched, but I am unable to find anything.
英文:
I am new to Typescript
and wanted to practice a library called redux-actions
. I followed this tutorial:
https://youtube.com/watch?v=8DH7Ekp2PWI&feature=shares
and I tried to use the redux-actions
tutorial
https://redux-actions.js.org/introduction/tutorial
but it does not work in jsfiddle or codepen, like they suggest, so I thought a better approach would be to modify the Youtube tutorial and use the redux-actions
library in the codebase from the YouTube video.
The codebase for the Youtube tutorial is on github.
https://github.com/Jon-Peppinck/react-redux-ts
However, I am having trouble with the actions and reducer components. Here is what I have tried
Counter.ts
export interface Counter {
count: number;
}
CounterActions.ts
import { createActions } from "redux-actions";
export const { increment, decrement } = createActions({
INCREMENT: (amount = 1) => ({ amount }),
DECREMENT: (amount = 1) => ({ amount: -amount }),
});
interface IncrementAction {
type: typeof increment;
}
interface DecrementAction {
type: typeof decrement;
}
export type CounterActionTypes = IncrementAction | DecrementAction;
CounterReducer.ts
import { handleActions } from "redux-actions";
import { CounterActionTypes, decrement, increment } from "./CounterAction";
import { Counter } from "./models/Counter";
const defaultState: Counter = {
count: 0,
};
export const counterReducer = handleActions(
{
[increment]: (state: Counter, { payload: { amount } }: any): Counter => {
return { ...state, count: state.count + amount };
},
[decrement]: (state: Counter, { payload: { amount } }: any): Counter => {
return { ...state, count: state.count + amount };
},
},
defaultState
);
But the increment and decrement actions are showing an error:
> A computed property name must be of type 'string', 'number', 'symbol', or 'any'.ts(2464)
I am also not sure of the way I have typed the payload
using any
, is there a better way to type it. How can I fix my code and prevent the errors? Also, are there any resources or tutorials on using redux-actions that are not paid content. I searched, but I am unable to find anything.
答案1
得分: 2
我是 Redux 的维护者。
请 不要 使用 redux-actions
!
它已经过时,使用它将需要编写许多您 不需要 编写的代码。
相反,今天您应该使用我们官方的 Redux Toolkit 包。RTK 已经被设计用于简化和标准化 Redux 的使用模式,并且与 TypeScript 配合非常出色。
这是使用 RTK 的示例(还有一个额外的情况减少器作为奖励):
// 文件:src/features/counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface CounterState {
value: number;
}
const initialState: CounterState = {
value: 0
}
const counterSlice = createSlice({
name: "counter",
initialState,
// `reducers` 字段允许我们定义减少器并生成相关的操作
reducers: {
increment: (state) => {
// Redux Toolkit 允许我们在减少器中编写“变异”逻辑。它
// 实际上不会改变状态,因为它使用 Immer 库,
// 该库检测对“草稿状态”的更改并根据这些更改生成全新的
// 不可变状态
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
}
}
})
export const {
increment,
decrement,
incrementByAmount
} = counterSlice.actions;
export default counterSlice.reducer
请查看我们的文档,了解如何以及为什么使用 Redux Toolkit 的详细信息:
- https://redux.js.org/introduction/why-rtk-is-redux-today
- https://redux.js.org/tutorials/essentials/part-2-app-structure
- https://redux.js.org/tutorials/fundamentals/part-8-modern-redux
- https://redux.js.org/tutorials/typescript-quick-start
英文:
I'm a Redux maintainer.
Please do not use redux-actions
!
It's outdated, and using it will require writing a lot of code that you don't need to write.
Instead, today you should be using our official Redux Toolkit package. RTK has been designed to simplify and standardize Redux usage patterns, and also work great with TypeScript.
Here's what your example would look like with RTK (and an extra case reducer as a bonus):
// File: src/features/counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
interface CounterState {
value: number;
}
const initialState : CounterState = {
value: 0
}
const counterSlice = createSlice({
name: "counter",
initialState,
// The `reducers` field lets us define reducers and generate associated actions
reducers: {
increment: (state) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
}
}
})
export const {
increment,
decrement,
incrementByAmount
} = counterSlice.actions;
export default counterSlice.reducer
Please see our docs for details on how and why to use Redux Toolkit:
答案2
得分: 0
以下是翻译好的部分:
似乎问题出在[increment]
,我不明白为什么文档中是这样的,但嘿,它已经有4年了。
但对我有效的是这个:
CounterActions.ts
import { createActions } from 'redux-actions'
export interface ActionPayload {
amount: number
}
export enum ActionNames {
INCREMENT = 'increment',
DECREMENT = 'decrement',
}
export const { increment, decrement } = createActions<ActionPayload>({
[ActionNames.INCREMENT]: (amount = 1) => ({ amount }),
[ActionNames.DECREMENT]: (amount = 1) => ({ amount: -amount }),
})
interface IncrementAction {
type: typeof increment
}
interface DecrementAction {
type: typeof decrement
}
export type CounterActionTypes = IncrementAction | DecrementAction
CounterReducer.ts
import { handleActions } from 'redux-actions'
import { ActionNames, ActionPayload } from './CounterAction'
import { Counter } from './models/Counter'
const defaultState: Counter = {
count: 0,
}
export const counterReducer = handleActions<Counter, ActionPayload>(
{
[ActionNames.INCREMENT]: (state, { payload: { amount } }) => {
return { ...state, count: state.count + amount }
},
[ActionNames.DECREMENT]: (state, { payload: { amount } }) => {
return { ...state, count: state.count + amount }
},
},
defaultState
)
英文:
Seems the issue is in the [increment]
, I don't get why it's that way in the documentation, but hey, it's 4 years old.
But what worked for me is this:
CounterActions.ts
import {createActions} from 'redux-actions'
export interface ActionPayload {
amount: number
}
export enum ActionNames {
INCREMENT = 'increment',
DECREMENT = 'decrement',
}
export const {increment, decrement} = createActions<ActionPayload>({
[ActionNames.INCREMENT]: (amount = 1) => ({amount}),
[ActionNames.DECREMENT]: (amount = 1) => ({amount: -amount}),
})
interface IncrementAction {
type: typeof increment
}
interface DecrementAction {
type: typeof decrement
}
export type CounterActionTypes = IncrementAction | DecrementAction
CounterReducer.ts
import {handleActions} from 'redux-actions'
import {ActionNames, ActionPayload} from './CounterAction'
import {Counter} from './models/Counter'
const defaultState: Counter = {
count: 0,
}
export const counterReducer = handleActions<Counter, ActionPayload>(
{
[ActionNames.INCREMENT]: (state, {payload: {amount}}) => {
return {...state, count: state.count + amount}
},
[ActionNames.DECREMENT]: (state, {payload: {amount}}) => {
return {...state, count: state.count + amount}
},
},
defaultState
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论