笔记:
1. mapStateToProps中,使用state._time.xxx的原因是,_time是reducer函数的名字。
// 这是我们的 select 函数, 它会把我们需要在属性 (prop) 中对我们的组件暴露的数据从 state 中抽离出来 const mapStateToProps = (state/*, props*/) => { console.log("last state", state) return { frozen: state._time.frozen, time: state._time.time, // 像 (reduxState: state) 这样提供整个 state 是一种不好的实现, // 我们在这里这样写是为了让大家能看到我们页面字符串化的结果。更多信息请访问以下链接: // https://github.com/reactjs/react-redux/blob/master/docs/api.md#inject-dispatch-and-every-field-in-the-global-state reduxState: state, } }
// 章节 12 - Provider-and-connect.js // 这个文件包含我们应用仅有的一个 reducer。 它的表现对于你来说没什么新鲜的,除了将一个 action(GET_TIME) 的3个方面,写成3个专用的 action... // 这样做允许我们做很漂亮的实时UI更新,就像这样: // 1) 当收到 GET_TIME_REQUEST action,我们修改 state 来告诉 UI 的一部分需要被冻结(因为有一个挂起的操作) // 2) 当收到 GET_TIME_SUCCESS (或 GET_TIME_FAILURE)之后,我们修改 state 为不冻结应用程序,然后添加收到的新数据。 var initialTimeState = {} // 下面的 reducer 命名用"_"开头,用于从 state 中读取的时候,避免 state.time.time (出现两个 time )。 // 这只是个人偏好你可以不必这样做,它取决于你如何对各个 reducer 命名,和在 Redux 的 store 中暴露哪些属性。 export function _time(state = initialTimeState, action) { console.log('_time reducer called with state ', state , ' and action ', action); switch (action.type) { case 'GET_TIME_REQUEST': return { ...state, frozen: true } case 'GET_TIME_SUCCESS': return { ...state, time: action.result.time, frozen: false } case 'GET_TIME_FAILURE': // 这里我们可以添加一个错误消息,打印到我们应用程序的某个地方 return { ...state, frozen: false } default: return state } }
2.在connect源码中。
在componentDidMount执行了订阅subscribe操作;
subscribe订阅了listener:handChange;
handleChange中执行了this.setState操作更新state。
Connect.prototype.componentDidMount = function componentDidMount() { this.trySubscribe(); }; Connect.prototype.trySubscribe = function trySubscribe() { if (shouldSubscribe && !this.unsubscribe) { this.unsubscribe = this.store.subscribe(this.handleChange.bind(this)); this.handleChange(); } }; Connect.prototype.handleChange = function handleChange() { if (!this.unsubscribe) { return; } this.setState({ storeState: this.store.getState() }); };