Newly using ARc (Atomic React) for a project (which is great and I think has a ton of future-proofing for what is ultimately going to be an enterprise-level product), BUT it's only future proof if I don't puzzle it together incorrectly and I currently can't get my head around how/when/where/why to use selectors in my app.
Have read this: How is state passed to selectors in a react-redux app? which is great, but I think need to see a few more examples to actually get it.
Current problem I'm trying to solve is getting a user
object (which is accessible app-wide) and also, with that data, creating a view-friendly slice of state for an account settings page where the user can modify their own name, email, etc. I wouldn't want to just use the user
store because don't want them changing anything until they actually hit submit, but do want to maintain form state in redux.
I load in my user which is all good (can access it via props on different containers where I want): Actions:
export const USER_GET_REQUEST = 'USER_GET_REQUEST'
export const USER_GET_REQUEST_SUCCESS = 'USER_GET_REQUEST_SUCCESS'
export const USER_GET_REQUEST_FAILURE = 'USER_GET_REQUEST_FAILURE'
export const getUserRequest = (params, resolve, reject) => ({
type: USER_GET_REQUEST,
params,
resolve,
reject,
})
export const getUserRequestSuccess = user => ({
type: USER_GET_REQUEST_SUCCESS,
user,
})
export const getUserRequestFailure = error => ({
type: USER_GET_REQUEST_FAILURE,
error,
})
Sagas:
import { take, put, call, fork } from 'redux-saga/effects'
import api from 'services/api'
import * as actions from './actions'
export function* readGetUser() {
try {
const data = yield call(api.get, '/user')
yield put(actions.getUserRequestSuccess(data))
} catch (e) {
yield put(actions.getUserRequestFailure(e))
}
}
export function* watchUserGetRequest() {
while (true) {
const { params } = yield take(actions.USER_GET_REQUEST)
yield call(readGetUser, params)
}
}
export default function* () {
yield fork(watchUserGetRequest)
}
Reducer:
import { initialState } from './selectors'
import { USER_LOGIN_SUCCESS, USER_GET_REQUEST_SUCCESS } from './actions'
export default (state = initialState, action) => {
switch (action.type) {
case USER_LOGIN_SUCCESS:
return state
case USER_GET_REQUEST_SUCCESS:
return {
...state,
user: action.user,
}
default:
return state
}
}
Selector (my nonsense code commented, single line works as far as making user
actually have the user data, but WHERE DOES COMPUTED DATA GO/HOW DOES IT GET THERE.
export const initialState = {
user: {},
}
export const getUser = (state = initialState) => state.user || initialState.user
// export const getUser = (state = initialState) => {
// if (state.user) {
// return Object.assign({}, state, {
// formData: {
// firstName: state.user.firstName,
// lastName: state.user.lastName,
// email: state.user.email,
// phone: state.user.phone,
// },
// })
// }
//
// return initialState.user
// }
Code help is amazing, clear explanations get my unwavering affection and gratitude + a mention in my autobiography.