Code to be refactored:
Let nexttodoid = 0; class Todoapp extends Component {render () {const {todos, visibilityfilter}= This. Props; Const Visibletodos=Getvisibletodos (Todos, visibilityfilter); return ( <div> <input Ref={node = { This. Input =node; }} /> <button onclick={() ={store.dispatch ({type:' Add_todo ', Text: This. Input.value, Id:nexttodoid++ }); This. Input.value = "; }}>ADD Todo</button> <ul>{visibletodos.map (Todo= <li key={todo.id} onClick={() ={store.dispatch ({type:' Toggle_todo ', id:todo.id}); }} Style={{textDecoration:todo.completed? ' Line-through ' : ' None ' }}>{Todo.text}</li> )} </ul><p> Show: {'} <filterlink filter= ' Show_all ' Curren Tfilter={visibilityfilter} > All </FilterLink> {', '} <filterli NK filter= ' show_active ' currentfilter={visibilityfilter} > ACTIVE &L t;/filterlink> {', '} <filterlink filter= ' show_completed ' Currentfilter={vis Ibilityfilter} > completed </FilterLink> </p></div> ); }}
Const Filterlink = ({ filter, currentfilter, = = {if (filter = = = CurrentFilter) { return <span>{children}</span>; } return ( <a href= ' # ' onClick={e = { e.preventdefault (); Store.dispatch ({ ' set_visibility_filter ', FILTER });} } > {children} </a> );};
Refactor footer part to a functional component, which contains all these three filter links. Pass in Visibilityfilter as props:
Const Footer =({visibilityfilter})= ( <p>Show: {‘ ‘} <Filterlink Filter= ' Show_all 'CurrentFilter={Visibilityfilter}> All</FilterLink> {', '} <Filterlink Filter= ' show_active 'CurrentFilter={Visibilityfilter}>Active</FilterLink> {', '} <Filterlink Filter= ' show_completed 'CurrentFilter={Visibilityfilter}>completed</FilterLink> </p>);
In the Filterlink, we want is presentational components. However, the filter link includes a short dispatch call. I am replacing it with a on click Call. I Pass the filter as the parameter for the calling component ' s convenience. I add on Click to the props.
Const Filterlink = ({ filter, currentfilter, children, = = {if ( Filter = = = CurrentFilter ) {return <span>{children}</span>; } return ( <a href= ' # ' onClick={e = { e.preventdefault (); Onfilterclick (filter);} } > {children} </a> );};
Const Footer =({visibilityfilter, onfilterclick})= ( <p>Show: {‘ ‘} <Filterlink Filter= ' Show_all 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}> All</FilterLink> {', '} <Filterlink Filter= ' show_active 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}>Active</FilterLink> {', '} <Filterlink Filter= ' show_completed 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}>completed</FilterLink> </p>);
-----------------------------------
Code:
Const TODO = (state, action) = = { Switch(action.type) { Case' Add_todo ': return{id:action.id, text:action.text, completed:false }; Case' Toggle_todo ': if(State.id!==action.id) {returnState ; } return{... state, completed:!state.completed}; default: returnState ; }};const Todos= (state = [], action) = = { Switch(action.type) { Case' Add_todo ': return[... state, Todo (undefined, action)]; Case' Toggle_todo ': returnState.map (t =Todo (T, action)); default: returnState ; }};const Visibilityfilter=( State= ' Show_all ', Action)= { Switch(action.type) { Case' Set_visibility_filter ': returnAction.filter; default: returnState ; }};const {combinereducers}=Redux;const Todoapp=combinereducers ({todos, visibilityfilter}); const {CreateStore}=Redux;const Store=CreateStore (Todoapp); const {Component}=React;/** Functional compoment, persental compoment:doesn ' t need to know-do, just show the interface, call the Callba ck function.*/Const Addtodo=({Onaddtodo})={let input; return ( <div> <input Ref={node ={input=node; }} /> <button onclick={() ={Onaddtodo (input.value); Input.value= ' '; }}>ADD Todo</button> </div> );}/*Functional Component*/Const Footer=({visibilityfilter, onfilterclick})= ( <p>Show: {‘ ‘} <Filterlink Filter= ' Show_all 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}> All</FilterLink> {', '} <Filterlink Filter= ' show_active 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}>Active</FilterLink> {', '} <Filterlink Filter= ' show_completed 'CurrentFilter={visibilityfilter} onfilterclick={Onfilterclick}>completed</FilterLink> </p>); Const Filterlink=({filter, currentfilter, children, Onfilterclick})= { if(Filter = = =CurrentFilter) { return<span>{children}</span>; } return ( <a href= ' # 'OnClick={e ={e.preventdefault (); Onfilterclick (filter); }} >{Children}</a> );}; 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); }}let nexttodoid= 0; class Todoapp extends Component {render () {const {todos, visibilityfilter}= This. Props; Const Visibletodos=Getvisibletodos (Todos, visibilityfilter); return ( <div> <Addtodo Onaddtodo={Text =Store.dispatch ({type:' Add_todo ', Id:nexttodoid++, text}) } /> <ul>{visibletodos.map (Todo= <li key={todo.id} onClick={() ={store.dispatch ({type:' Toggle_todo ', id:todo.id}); }} Style={{textDecoration:todo.completed? ' Line-through ' : ' None ' }}>{Todo.text}</li> )} </ul> <Footer Visibilityfilter={visibilityfilter} onfilterclick={(Filter) ={store.dispatch ({type:' Set_visibility_filter ', filter}); }} /> </div> ); }}const Render= () + ={Reactdom.render (<Todoapp {... store.getstate ()}/>, document.getElementById (' root ') );}; Store.subscribe (render); render ();
[Redux] Extracting presentational components--Footer, Filterlink