thecodingmachine / redux-toolkit-wrapper

Redux-toolkit wrapper used to write less code regarding classic CRUD operations.
MIT License
19 stars 5 forks source link

More detailed documentation #3

Closed Angelk90 closed 3 years ago

Angelk90 commented 3 years ago

Hi @AurelGit , @JeremyDolle :

It would be possible to have more information on how to use it, with some examples.

I am trying to use it but I am having problems.

In the boilerplate where it is used, inside store I created a folder called Settings.

Store/Settings/index.js

import { buildSlice } from '@thecodingmachine/redux-toolkit-wrapper'
import InitSettings from './Init'

const sliceInitialState = {
  item: {},
  ok: true
}

export default buildSlice('settings', [InitSettings], sliceInitialState).reducer

Store/Settings/Init.js

import {
  buildAsyncState,
  buildAsyncActions,
  buildAsyncReducers,
} from '@thecodingmachine/redux-toolkit-wrapper'
import FetchOne from '@/Store/User/FetchOne'

export default {
  initialState: buildAsyncState(),
  action: buildAsyncActions('settings/init', async (args, { dispatch }) => {
    console.log("Settings", args)
    // Timeout to fake waiting some process
    // Remove it, or keep it if you want display a beautiful splash screen ;)
    await new Promise((resolve) => setTimeout(resolve, 1000))
    // Here we load the user 1 for example, but you can for example load the connected user
    await dispatch({
      theme: "dark",
      lang: "it"
    })
  }),
  reducers: buildAsyncReducers({ itemKey: null }), // We do not want to modify some item by default
}

In Store's index.js file I did this, added settings and whitelisted it:

import AsyncStorage from '@react-native-async-storage/async-storage'
import { combineReducers } from 'redux'
import {
  persistReducer,
  persistStore,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist'
import { configureStore } from '@reduxjs/toolkit'

import startup from './Startup'
import user from './User'
import settings from './Settings'

const reducers = combineReducers({
  settings,
  startup,
  user,
})

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  whitelist: [settings],
}

const persistedReducer = persistReducer(persistConfig, reducers)

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) => {
    const middlewares = getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    })

    if (__DEV__ && !process.env.JEST_WORKER_ID) {
      const createDebugger = require('redux-flipper').default
      middlewares.push(createDebugger())
    }

    return middlewares
  },
})

const persistor = persistStore(store)

export { store, persistor }

But it's not working, when I do this:

const st = useSelector((state) => state)
console.log(st.settings)

I am printed this in console:

{"error": null, "item": {}, "loading": false, "ok": true}

What I would like him to return to me is this:

{
      theme: "dark",
      lang: "it"
 }
loikfb commented 3 years ago

Hi @Angelk90, I agree that a more detailed doc for this part would be nice. I think we can refer to the wrapped Redux toolkit doc for the moment: https://redux-toolkit.js.org/

For your problem: 1) It seems that you forgot to dispatch your "Settings" action in "IndexStartupContainer" for example.

useEffect(() => {
    dispatch(InitSettings.action())
  }, [dispatch])

2) The dispatched object will be in item so if you want to access it via a selector it will be state.settings.item instead of state.settings

JeremyDolle commented 3 years ago

Hi, We are currently working on the doc. As @loikfb mention it, you need to understand redux and reduxtoolkit. We will provide really soon an update of the documentation 😉

Don't forget, everything which comes from this helper is for asynchronous API calls, that why you will have loading, error.

Angelk90 commented 3 years ago

@loikfb , @JeremyDolle :

I tried to change a few things:

const settings = useSelector((state) => state.settings.item)
console.log("s:", settings)

Store/Settings/index.js

import { buildSlice } from '@thecodingmachine/redux-toolkit-wrapper'
import InitSettings from './Init'

const sliceInitialState = {
  item: {
    colorScheme: "light",
    lang: "fr",
  }
}

export default buildSlice('settings', [InitSettings], sliceInitialState).reducer

Store/Settings/Init.js

import {
  buildAsyncState,
  buildAsyncActions,
  buildAsyncReducers,
} from '@thecodingmachine/redux-toolkit-wrapper'

export default {
  initialState: buildAsyncState(),
  action: buildAsyncActions('settings/init', async (args, { dispatch }) => {
    console.log("Settings", args)
    // Timeout to fake waiting some process
    // Remove it, or keep it if you want display a beautiful splash screen ;)
    await new Promise((resolve) => setTimeout(resolve, 1000))
    // Here we load the user 1 for example, but you can for example load the connected user
    return {
      colorScheme: args.colorScheme,
      lang: "fr",
    }
    /*dispatch({
        type: 'SOME_TYPE',
        payload: {
          colorScheme: args.colorScheme,
          lang: "fr",
        }
    })*/
  }),
  reducers: buildAsyncReducers({
    //errorKey: false,
    //loadingKey: false,
    itemKey: 'item'
  })
}

Let's start with the questions:

1) This way with the return it seems to work, but if I wanted to use dispatch as I should (commented part in the file).

2) If instead of putting it inside item or another key, using itemKey I want to put it in the main object how can I do. That is to have the information in state.setting.

3) To make this information persistent as I should do. For example I allow the user to change the theme (light or dark), I would like this information to be persistent, i.e. when I restart app I have this information saved so that I can retrieve it. I whitelisted it, but I don't know how to save this information. If this information does not exist, retrieve the default one for example.

Angelk90 commented 3 years ago

@AurelGit, @JeremyDolle, @loikfb : Can you help me?

JeremyDolle commented 3 years ago

Hi, I make a little fix in order to be able to use the same way the buildslice for async action or simple action. It will be merge really soon.

Here the problem you have is that you use buildAsync. With the prefix buildAsync you will have the loading and the error entries. So it's for API calls or async function that needs to be waited. Take a look at redux-toolkit documentation and use their function for simple redux action handlers (without async logic).

I come to you when the fix is release ! See you really soon !

For the whitelist you just need to add le slice name into it like this:

Whitelist:["settings"]

The state under the settings key will be stored. At the launch the action REHYDRATE will be trigger and all stored information will be merge to the state thanks to the persistProvider

Angelk90 commented 3 years ago

@JeremyDolle :

1) It seems to me that there are errors in the doc.

In: https://github.com/thecodingmachine/redux-toolkit-wrapper#usage

There is no redux-toolkit-wrapper module with buildAction, buildReducers.

In: https://thecodingmachine.github.io/react-native-boilerplate/docs/ReduxStore

There are two cases where they are pending, one should not be rejected.

2)

When it comes to saving, see the buildSlice code.

Should I use extraReducers, if how should I do? https://github.com/thecodingmachine/redux-toolkit-wrapper/blob/master/src/wrappers/slice/buildSlice.js#L15

I tried to do this, but it doesn't seem to work:

export default buildSlice ('settings', [InitSettings], sliceInitialState,
(builder) => {console.log ("builder", builder)}
) .reducer

I have to create an action like this:

const addTodo = createAction ('init', function prepare (text) {
   console.log (text)
   return {
     payload: {
       colorScheme: "dark", lang: "fr"
     },
   }
})

I'm not understanding how to do it. :(

JeremyDolle commented 3 years ago

Yes the documentation will be updated with the fix, be patient. For the moment, if you want to make simple action (without API calls) just use redux toolkit

JeremyDolle commented 3 years ago

the updated documentation : https://thecodingmachine.github.io/react-native-boilerplate/docs/ReduxStore