2023-12-05 15:28:35 13阅读
只负责 UI 的呈现,不带有任何业务逻辑 没有状态(即不使用this.state这个变量) 所有数据都由参数(this.props)提供 不使用任何 Redux 的 API
const Title= value=><h1>{value}</h1>;
负责管理数据和业务逻辑,不负责 UI 的呈现 带有内部状态 使用 Redux 的 API
import{connect}from'react-redux' const VisibleTodoList=connect()(TodoList);
(1)输入逻辑:外部的数据(即state对象)如何转换为 UI 组件的参数(2)输出逻辑:用户发出的动作如何变为 Action 对象,从 UI 组件传出去。
import{connect}from'react-redux' const VisibleTodoList=connect( mapStateToProps, mapDispatchToProps )(TodoList)
const mapStateToProps=(state)=>{ return{ todos:getVisibleTodos(state.todos,state.visibilityFilter) } }
const getVisibleTodos=(todos,filter)=>{ switch(filter){ case'SHOW_ALL': returntodos case'SHOW_COMPLETED': returntodos.filter(t=>t.completed) case'SHOW_ACTIVE': returntodos.filter(t=>!t.completed) default: thrownewError('Unknown filter: '+filter) } }
// 容器组件的代码 // <FilterLink filter="SHOW_ALL"> // All // </FilterLink> const mapStateToProps=(state,ownProps)=>{ return{ active:ownProps.filter===state.visibilityFilter } }
const mapDispatchToProps=( dispatch, ownProps )=>{ return{ onClick:()=>{ dispatch({ type:'SET_VISIBILITY_FILTER', filter:ownProps.filter }); } }; }
const mapDispatchToProps={ onClick:(filter)=>{ type:'SET_VISIBILITY_FILTER', filter:filter }; }
import{Provider}from'react-redux' import{createStore}from'redux' import todoApp from'./reducers' import App from'./components/App' letstore=createStore(todoApp); render( <Provider store={store}> <App/> </Provider>, document.getElementById('root') )
classProviderextendsComponent{ getChildContext(){ return{ store:this.props.store }; } render(){ returnthis.props.children; } } Provider.childContextTypes={ store:React.PropTypes.object }
classVisibleTodoListextendsComponent{ componentDidMount(){ const{store}=this.context; this.unsubscribe=store.subscribe(()=> this.forceUpdate() ); } render(){ const props=this.props; const{store}=this.context; const state=store.getState(); // ... } } VisibleTodoList.contextTypes={ store:React.PropTypes.object }
classCounterextendsComponent{ render(){ const{value,onIncreaseClick}=this.props return( <div> <span>{value}</span> <button onClick={onIncreaseClick}>Increase</button> </div> ) } }
functionmapStateToProps(state){ return{ value:state.count } } functionmapDispatchToProps(dispatch){ return{ onIncreaseClick:()=>dispatch(increaseAction) } } // Action Creator const increaseAction={type:'increase'}
const App=connect( mapStateToProps, mapDispatchToProps )(Counter)
// Reducer functioncounter(state={count:0},action){ const count=state.count switch(action.type){ case'increase': return{count:count+1} default: returnstate } }
import{loadState,saveState}from'./localStorage'; const persistedState=loadState(); const store=createStore( todoApp, persistedState ); store.subscribe(throttle(()=>{ saveState({ todos:store.getState().todos, }) },1000)) ReactDOM.render( <Provider store={store}> <App/> </Provider>, document.getElementById('root') );
const Root=({store})=>( <Provider store={store}> <Router> <Route path="/"component={App}/> </Router> </Provider> );
2023-12-05 15:28:35 13阅读
只负责 UI 的呈现,不带有任何业务逻辑 没有状态(即不使用this.state这个变量) 所有数据都由参数(this.props)提供 不使用任何 Redux 的 API
const Title= value=><h1>{value}</h1>;
负责管理数据和业务逻辑,不负责 UI 的呈现 带有内部状态 使用 Redux 的 API
import{connect}from'react-redux' const VisibleTodoList=connect()(TodoList);
(1)输入逻辑:外部的数据(即state对象)如何转换为 UI 组件的参数(2)输出逻辑:用户发出的动作如何变为 Action 对象,从 UI 组件传出去。
import{connect}from'react-redux' const VisibleTodoList=connect( mapStateToProps, mapDispatchToProps )(TodoList)
const mapStateToProps=(state)=>{ return{ todos:getVisibleTodos(state.todos,state.visibilityFilter) } }
const getVisibleTodos=(todos,filter)=>{ switch(filter){ case'SHOW_ALL': returntodos case'SHOW_COMPLETED': returntodos.filter(t=>t.completed) case'SHOW_ACTIVE': returntodos.filter(t=>!t.completed) default: thrownewError('Unknown filter: '+filter) } }
// 容器组件的代码 // <FilterLink filter="SHOW_ALL"> // All // </FilterLink> const mapStateToProps=(state,ownProps)=>{ return{ active:ownProps.filter===state.visibilityFilter } }
const mapDispatchToProps=( dispatch, ownProps )=>{ return{ onClick:()=>{ dispatch({ type:'SET_VISIBILITY_FILTER', filter:ownProps.filter }); } }; }
const mapDispatchToProps={ onClick:(filter)=>{ type:'SET_VISIBILITY_FILTER', filter:filter }; }
import{Provider}from'react-redux' import{createStore}from'redux' import todoApp from'./reducers' import App from'./components/App' letstore=createStore(todoApp); render( <Provider store={store}> <App/> </Provider>, document.getElementById('root') )
classProviderextendsComponent{ getChildContext(){ return{ store:this.props.store }; } render(){ returnthis.props.children; } } Provider.childContextTypes={ store:React.PropTypes.object }
classVisibleTodoListextendsComponent{ componentDidMount(){ const{store}=this.context; this.unsubscribe=store.subscribe(()=> this.forceUpdate() ); } render(){ const props=this.props; const{store}=this.context; const state=store.getState(); // ... } } VisibleTodoList.contextTypes={ store:React.PropTypes.object }
classCounterextendsComponent{ render(){ const{value,onIncreaseClick}=this.props return( <div> <span>{value}</span> <button onClick={onIncreaseClick}>Increase</button> </div> ) } }
functionmapStateToProps(state){ return{ value:state.count } } functionmapDispatchToProps(dispatch){ return{ onIncreaseClick:()=>dispatch(increaseAction) } } // Action Creator const increaseAction={type:'increase'}
const App=connect( mapStateToProps, mapDispatchToProps )(Counter)
// Reducer functioncounter(state={count:0},action){ const count=state.count switch(action.type){ case'increase': return{count:count+1} default: returnstate } }
import{loadState,saveState}from'./localStorage'; const persistedState=loadState(); const store=createStore( todoApp, persistedState ); store.subscribe(throttle(()=>{ saveState({ todos:store.getState().todos, }) },1000)) ReactDOM.render( <Provider store={store}> <App/> </Provider>, document.getElementById('root') );
const Root=({store})=>( <Provider store={store}> <Router> <Route path="/"component={App}/> </Router> </Provider> );