有太多的教程都讲着稍微不同的标准和约定,将Redux Saga迁移到React钩子的最佳实践是什么?
答案 0 :(得分:1)
以下是我正在使用的方法,请预先准备。
constants/index.js
export const SET_NARRATIVE = 'SET_NARRATIVE'
actions/narrative.js
组件将其称为调度动作
export const setNarrative = narrative => {
return {
type: SET_NARRATIVE,
narrative,
}
}
使用此narrativeSet
最好与Saga命名约定匹配,但在组件中不太可读。
reducers/narrative.js
发现已调度的动作并从组件到商店应用更新。
export const narrativeReducer = (state = narrativeInitialState, action) => {
switch (action.type) {
case SET_NARRATIVE:
return {
...state,
narrative: action.narrative,
} ...
reducers/index.js
将Reducer连接到Redux动作/事件循环
const reducers = combineReducers({
narrative: narrativeReducer,
components/Draft.js
将组件连接到Redux状态和调度程序。认为最佳实践是对连接的组件使用containers/
,但是我的大多数组件都已连接。
从this.props.narrative
读取,然后使用this.props.setNarrative(narrative)
写入。
import { setNarrative } from '../actions/narrative'
const mapStateToProps = state => ({
narrative: state.narrative.narrative, // processing here if necessary
})
const mapDispatchToProps = { setNarrative }
Draft = connect(
mapStateToProps,
mapDispatchToProps
)(Draft)
export default Draft
constants/index.js
export const NARRATIVE_FETCH_REQUESTED = 'NARRATIVE_FETCH_REQUESTED'
export const NARRATIVE_FETCH_SUCCEEDED = 'NARRATIVE_FETCH_SUCCEEDED'
export const NARRATIVE_FETCH_FAILED = 'NARRATIVE_FETCH_FAILED'
actions/narrative.js
通过id请求叙述,并“输入”结果或错误的操作。
export const narrativeFetchRequested = id => {
return {
type: NARRATIVE_FETCH_REQUESTED,
id,
}
}
export const narrativeFetchSucceeded = narrative => {
return {
type: NARRATIVE_FETCH_SUCCEEDED,
narrative,
}
}
export const narrativeFetchFailed = error => {
return {
type: NARRATIVE_FETCH_FAILED,
error,
}
}
reducers/narrative.js
在Redux Store中存储获取状态,结果和/或错误。
case NARRATIVE_FETCH_REQUESTED:
return {
...state,
narrativeLoading: true,
}
case SET_NARRATIVE: ) // non-Saga version above
case NARRATIVE_FETCH_SUCCEEDED:
return {
...state,
narrative: action.narrative,
narrativeLoading: false,
}
case NARRATIVE_FETCH_FAILED:
return {
...state,
narrative: null,
narrativeLoading: false,
error: action.error,
}
reducers/index.js
const reducers = combineReducers({
narrative: narrativeReducer, // as above
api/index.js
export const getNarrative = id => {
return axios.get(`${API_URL}narratives/${id}/`)
}
sagas/narrative.js
发送请求到API,处理返回的数据,然后调度(放置)操作以更新商店。
export function* fetchNarrative(action) {
try {
const { id } = action
const { data: narrative } = yield call(getNarrative, id)
createPermissionShortcuts(narrative) // some off-thread processing
narrative.updated_display = renderDate(narrative.updated) // Python backend naming convention
yield put(fetchNarrativeSucceeded(narrative))
} catch (error) {
yield put(fetchNarrativeFailed(error))
}
}
export function* watchNarrativeRequested() {
yield takeEvery(NARRATIVE_FETCH_REQUESTED, fetchNarrative)
}
sagas/index.js
export default function* rootSaga() {
yield all([
watchNarrativeRequested(),
...
在containers/App.js
中,在应用启动时运行Saga:
sagaMiddleware.run(fetchNarrative) // to trigger on app start
..和/或..
在components/Section.js
中从组件运行:
this.props.fetchNarrativeRequested(id)
触发this.props.narrativeLoading === true
this.props.narrative
this.props.narrativeError
读取错误class Section extends React.Component {
componentDidMount() { // in your component - render then fetch
this.props.narrativeFetchRequested(this.props.match.params.id) //if router parse url
} ...
}
const mapStateToProps = state => {
return {
narrative: state.narrative.narrative,
narrativeLoading: state.narrative.narrativeLoading,
narrativeError: state.narrative.error,
}
}
const mapDispatchToProps = {
narrativeFetchRequested,
}
Section = connect(
mapStateToProps,
mapDispatchToProps
)(Section)
export default Section