I am new to React/NextJS with Redux in TypeScript and I feel that the Redux setup is pretty ugly and I was wondering if there is a better way to do it. I created the store, reducers and actions following common tutorials Then wire up the _app.tsx this way:
import { Provider } from 'react-redux'
import store from '@store/store'
function MyApp({ Component, pageProps }: AppProps) {
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
}
export default MyApp
then wire up state to props and connect to redux in my index.tsx this way:
import { StoreState } from '@store/reducers'
import {
IData1,
IData2,
function1,
function2,
function3,
function4,
function5,
} from '@store/actions'
interface IProps {
data1: IData1[]
data2: IData2
function1: Function
function2: Function
function3: Function
function4: Function
function5: Function
}
const _Home: NextPage<IProps> = (props) => {
const {
data1,
data2,
function1,
function2,
function3,
function4,
function5,
} = props
return (<div>
<SomeComponent fct5={fonction5}
</div>)
}
const mapStateToProps = (
state: StoreState
): { data1: IData1[]; data2: IData2 } => {
return { data1: state.data1, data2: state.data2 }
}
const Home = connect(mapStateToProps, {
function1,
function2,
function3,
function4,
function5,
})(_Home)
export default Home
First I had to import all the structure and functions to be used, then I had to declare the interface to be passed as props to my component, extract the props inside my component to actually use it. Also I had to do all the connect wiring with mapStateToProps and the functions.
I found it to be very cumbersome and feel redundant but maybe I am not doing the things right, so please let me know if there is a better, clearer way to do it.
Now if I want to use some of the redux actions or use stored data in other component what is my choice ? Do I have to do the connect wiring for all components the make use of the Redux actions and states ? Or just create a enormous interface in the top component and pass functions and data through component attributes and props like for function5 in the example ?
CodePudding user response:
Pointing you in an alternative direction: If you don't want to use react-redux, you can use React context and React dispatch. Reducers are then just functions that take in a state and an action and output another state.
React context:
import React, { useContext } from 'react'
// creating context using react
const context = React.createContext<T | null>(null);
// React hook for context
useContext(context);
// React typing for Actions that can be dispatched
React.Dispatch<Action>
CodePudding user response:
I'll recommend you use [Zustand][1] to handle your states instead of Redux or even Context api.
Zustand is easy to use and contains way less boilerplate. You also do not need to wrap Zustand around any of your components. This gives you much more freedom to do more with your state by doing less.
Here's an example:
inside my ./store
import create from "zustand";
import { MyCustomType } from "./types";
export const cartStateStore = create<MyCustomType>((set) => ({
open: false,
setOpen: (val) => set(() => ({ open: val })),
}));
then I can import the value into any component and use the hook:
import { MyCustomType } from "../lib/store";
const MyComponent = () => {
const open = MyCustomType ((state) => state.open);
const setOpen = MyCustomType ((state) => state.setOpen);
//setOpen(true)
//console.log(open)
}
As simple as this. No need for all the boilerplate that comes with Redux/contextapi [1]: https://github.com/pmndrs/zustand