2017-04-20 25 views
3

在项目中使用ARc(Atomic React)(这非常棒,我认为对于最终将要实现的内容,一个企业级的产品),但它只是未来的证明,如果我不把它们拼错在一起,我目前无法理解我的应用中如何/何时/何地/为何使用选择器。在react/redux/saga /选择器设置中努力工作

看过这个:How is state passed to selectors in a react-redux app?这很棒,但我认为还需要看几个实例才能真正得到它。

我试图解决的当前问题是获取一个user对象(可在整个应用程序范围内访问),并且通过该数据为用户可修改的帐户设置页创建一个友好的界面状态他们自己的名字,电子邮件等。我不想只使用user商店,因为他们不希望他们改变任何东西,直到他们实际上提交了,但是确实想用redux维护表单状态。

我在我的用户加载哪个都好(可以通过上,我想不同的容器道具访问): 操作:

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, 
}) 

传奇故事:

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) 
} 

减速机:

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 
    } 
} 

选择器(我的废话代码评论,单线作品尽可能使user实际上有用户数据,但在哪里计算数据转到/它是如何到达那里的。

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 
// } 

代码帮助是惊人的,清晰的解释让我坚定不移的感情和感激+在我的自传中提到。

+0

您能澄清一下问题吗?它主要归结为“我何时使用选择器功能”?我知道,Eesh, – markerikson

+0

。我写了这个问题,并重写了这个问题10次,试图从根本上解决混乱问题。是的,何时何地使用选择器函数,以及如何在这个特定的实例中分离出一些表单数据? – megkadams

+0

你需要阅读这个问题的每一个答案 - http://stackoverflow.com/q/35411423/1477051 –

回答

3

选择器功能可以并且应该用于任何想要从商店中提取特定数据片段的地方。把它们想象成“查询你的状态树”,就像SQL查询到数据库中一样。

它们在您的mapStateToProps函数中最常用于提取组件需要的数据,但也适用于需要基于存储内容运行条件逻辑的地方(如thunk动作创建者或sagas)。如果你愿意,你甚至可以在减速器中使用它们。

选择器通常使用reselect库创建,它记录输入。这意味着最终提供的“输出”功能只有在输入实际发生变化时才会运行。一个简单的例子可能是:

import {createSelector} from "reselect"; 

const selectUser = state => state.user; 

const selectUserFirstName = createSelector(
    selectUser, 
    user => user.firstName 
); 

const selectUserLastName = createSelector(
    selectUser, 
    user => user.lastName 
); 

const selectUserFullName = createSelector(
    [selectUserFirstName, selectUserLastName], 
    (firstName, lastName) => firstName + " " + lastName 
); 

在这个例子中,“名字+姓氏”选择将只有两个输入一个实际上已经改变了运行。否则,它将返回以前的缓存结果值。然后,这可能被用作:

const mapState = (state) => { 
    const userFullName = selectUserFullName(state); 

    return {userFullName}; 
} 

有关选择器的详细信息,请参阅我的React/Redux links listRedux Techniques#Selectors and Normalization部分。我也使用我的Practical Redux tutorial series中的选择器。 (作为相关说明,您可能需要阅读Practical Redux Part 8: Form Draft Data Management或我的链接列表中的React and Forms部分的一些文章。)

+0

因此,欣赏笔记,并兴奋地阅读。不知道为什么ARc(https://github.com/diegohaz/arc/tree/redux)没有使用重新选择框 - 是否有任何理由可以考虑不包括我应该留意的图书馆? – megkadams

+0

假设这只是他们选择包含在样板中的库的问题。鉴于它们包含了重新编排的传奇,我只是有点惊讶他们没有包括重新选择。但是,绝对没有理由不包括它。这是一个小巧的轻量级库,并且与Redux一起广泛使用。此外,请随时通过https://www.reactiflux.com的Reactiflux聊天频道下载并提出更多问题。我在美国时间晚上(@acemarke)闲逛,还有很多其他人也乐于回答问题。 – markerikson

+0

将马上退房!谢谢! :) – megkadams