【全栈React】第20天: Redux动作
使用Redux,我们来谈谈我们如何在我们的应用中实际修改Redux状态。 昨天,我们经历了整合我们的反应应用与Redux的困难部分。从现在起,我们将使用我们的Redux设置来定义函数。 现在,我们的演示应用能显示当前时间。但目前还没有任何方法可以更新到新的时间。现在,让我们修改这个。 触发更新回想一下,我们能在Redux中改变数据的唯一方法是通过一个动作创建者。昨天我们创建了一个Redux的store,但我们还没有为我们的store创造一个更新的方法。 我们 想要 的是我们的用户通过点击按钮来更新时间的能力。为了添加此函数,我们需要执行以下几个步骤:
我们已经实现了第三个步骤,所以我们还有两件事要做,才能让这个函数像我们预期的那样工作。 昨天,我们讨论了什么是动作,但不是真正的为什么我们使用这个东西叫 actionCreators 或他们是什么。 作为复习,动作是一个_必须_ 包含 export const FETCH_NEW_TIME = 'FETCH_NEW_TIME'; 作为快速审阅,我们的动作可以是具有 { type: types.FETCH_NEW_TIME,payload: new Date().toString() } 现在,我们需要在我们的 store.dispatch({ type: types.FETCH_NEW_TIME,payload: new Date().toString() }) 然而,这是相当糟糕的做法。我们将使用一个函数来返回一个动作,而不是直接发送该动作,该函数将 创建 该动作 (因此名称: actionCreator)。这为我们提供了一个更好的测试故事 (易于测试)、可重用性、文档化和逻辑封装。 让我们在一个名为 import * as types from './types'; export const fetchNewTime = () => ({ type: types.FETCH_NEW_TIME,payload: new Date().toString(),}) export const login = (user) => ({ type: types.LOGIN,payload: user }) export const logout = () => ({ type: types.LOGOUT,}) 现在,如果我们调用这个函数,什么都不会发生,除了返回一个动作对象。我们怎样才能让这个动作在store里分发? It gets called with the 让我们来看看这个动作。在我们的 import { fetchNewTime } from '../../redux/actionCreators'; // ... const mapDispatchToProps = dispatch => ({ updateTime: () => dispatch(fetchNewTime()) }) // ... export default connect( mapStateToProps,mapDispatchToProps,)(Home); 现在, const Home = (props) => { return ( <div className="home"> <h1>Welcome home!</h1> <p>Current time: {props.currentTime}</p> <button onClick={props.updateTime}> Update time </button> </div> ); } 虽然这个例子并不令人兴奋,但它确实展示了Redux的特点。想象一下,如果按钮获取新的鸣叫或我们有一个socket驱动更新到我们的Redux store。这个基本示例演示了Redux的完整功能。 [](#multi-reducers)多归约器现在,我们我们的应用有一个单一的归约器。这是目前的工作,因为我们只有少量的简单数据和 (想必) 只有一个人在这个应用工作。试想一下,在我们的应用中为_每一片数据_开发一个巨大的开关语句。 Ahhhhhhhhhhhhhh... Redux去营救!Redux有一种方法,我们把我们的Redux归约器分成多个归约器,每个都只负责状态树的叶子。 我们可以从 假设我们 (也许更现实一些) 想跟踪当前用户。让我们创建一个 touch src/redux/currentUser.js 我们将导出我们从 import * as types from './types' export const initialState = { user: {},loggedIn: false } export const reducer = (state = initialState,action) => { switch (action.type) { case types.LOGIN: return { ...state,user: action.payload,loggedIn: true}; case types.LOGOUT: return { ...state,user: {},loggedIn: false}; default: return state; } } 让我们更新我们的 import { createStore,combineReducers } from 'redux'; import { rootReducer,initialState } from './reducers' import { reducer,initialState as userInitialState } from './currentUser' export const configureStore = () => { const store = createStore( combineReducers({ time: rootReducer,user: reducer }),// root reducer { time: initialState,user: userInitialState },// our initialState ); return store; } export default configureStore; 现在,我们可以创建 export const login = (user) => ({ type: types.LOGIN,payload: user }) // ... export const logout = () => ({ type: types.LOGOUT,我们可以使用 actionCreators 像 |