深圳博纳网站建设,创办网站,如何申请小程序,平面设计作品集模板目录 一 核心代码
1.reducer
2.store.js
二 关于context API的使用
1. MyContext
2. createContext
3. ContextProvider
4. connect
三 组件验证效果
1. Todo
2. TodoList
3.TodoItem
4.TodoInput
5. App组件引入Todo组件 一 核心代码
1.reducer
// 新增列表数…目录 一 核心代码
1.reducer
2.store.js
二 关于context API的使用
1. MyContext
2. createContext
3. ContextProvider
4. connect
三 组件验证效果
1. Todo
2. TodoList
3.TodoItem
4.TodoInput
5. App组件引入Todo组件 一 核心代码
1.reducer
// 新增列表数据和改变数组数据
// 将业务逻辑拆分到一个单独文件中方便进行状态管理
import _ from lodash;export interface StateProps {id: number;text: string;isFinished: boolean;}export interface ActionProps {type: string;[key: string]: any;}interface IStateObjectProps {pickerArr: StateProps[];filterTag: SHOW_ALL|SHOW_FINISHED|SHOW_NOT_FINISH;dispatch: any;}
const reducer (state: IStateObjectProps, action: ActionProps) {console.log(state, action, reducer11111);const pickerArr0 _.get(state, pickerArr)||[];switch (_.get(action, type)) {case ADD:return {...state,pickerArr: [...pickerArr0, _.get(action, todo)]};case CHANGESTATUS:const pickerArr _.map(pickerArr0, (item) {if (item.id action.id) {return Object.assign({}, item, { isFinished: !_.get(item, isFinished) });}return item;})||[];return {...state,pickerArr,}case SET_VISIBILITY_FILTER: const filterTag action.filterTag;return {...state,filterTag,};default:return state || {};}};export default reducer
2.store.js
import React from react;
import reducer from ./reducer// compose执行顺序就是从后往前
const compose (...funcs) {if (funcs.length 0) return arg argreturn funcs.reduce((v, cur) (...args) (v(cur(...args))))
}function applyMiddleware(...args) {// 将中间件们变成一个数组const middlewares Array.from({ length: args.length }, (_, _key) args[_key]);return function (createStore) {return function () {const store createStore.apply(void 0, arguments);const middlewareAPI {getState: store.getState,dispatch: store.dispatch,};// map遍历中间件, 执行监听器函数, 形成新数组const chain middlewares.map((middleware) middleware(middlewareAPI));// 展开中间件,调整执行顺序,并传入store.dispatchconst dispatch compose(...chain)(store.dispatch);// 返回需要的存储数据(将dispatch合并进store对象)return {...store,dispatch,};};};
}function legacy_createStore(reducer, preloadedState) {let state preloadedState || null;const listeners [];const subscribe (fn) listeners.push(fn);const getState () state;const dispatch (action) {const state1 reducer(state, action);state state1// 因为是在获取到最新的state的值之后有执行的监听回调, 所以使用store.subscribe可以监听到最新的state的值!!!listeners.forEach((fn) fn());return state}return { getState, dispatch, subscribe }
}function createStore(reducer, preloadedState, enhancer) {if (typeof preloadedState function) {return preloadedState(legacy_createStore)(reducer)}if (typeof enhancer function) {return enhancer(legacy_createStore)(reducer, preloadedState)}return legacy_createStore(reducer, preloadedState)
}function createThunkMiddleware(extraArgument) {return ({ dispatch, getState }) next action {if (typeof action function) {return action(dispatch, getState, extraArgument)}return next(action)}
}const thunk createThunkMiddleware(xxxxxx);
const store applyMiddleware(thunk)(createStore)(reducer);
// 或者
// const store createStore(reducer, applyMiddleware(thunk));
// 或者
// const store createStore(reducer);console.log(store, oldState)
store.subscribe(() {const newState store.getState()// 数据可能变化需要监听最新的console.log(newState, newState);
})export default store;
二 关于context API的使用
1. MyContext
import React from react;const MyContext React.createContext({});export default MyContext
2. createContext
import React, {ReactNode, memo} from react;// 已经使用了React.createContext, 这个可以忽略, 只是为了展示createContext功能的简单代码
const createContext ({}) {let value {};const Provider memo((props: {children: ReactNode;value:{ dispatch: (arg1:any)void; getState:() any;};}) {value props.value;return {props.children}/;});const Consumer memo(({ children }: { children: any }) {return {typeof children function ? children(value) : children}/;});return { Provider, Consumer };
};export default createContext;3. ContextProvider
import React, { useState } from react;
import MyContext from ./MyContext;
import _ from lodash;
import store from ./store;const useReducer (state0, dispatch0) {const [state, dispatch] useState(state0);const dispatch1 (action) {dispatch0(action);dispatch(store.getState());};return [state, dispatch1]
}// 父组件
const ContextProvider ({ children }) {const [state, dispatch] useReducer(store.getState(), store.dispatch);return MyContext.Provider value{{getState: () state,dispatch}}{children}/MyContext.Provider;
};export default ContextProvider;
4. connect
import React from react;
import MyContext from ./MyContext;
import _ from lodash;// 模拟react-redux的 connect高阶函数
const connect (mapStateToProps, mapDispatchToProps) {return (Component) (props) wrapper(Component, { mapStateToProps, mapDispatchToProps, ...props });
};const wrapper (Comp, props) {const { mapStateToProps, mapDispatchToProps, ...rest } props;return (MyContext.Consumer{(store) {const dispatchs mapDispatchToProps(_.get(store, dispatch));let states1 mapStateToProps(_.get(store, getState) ? _.get(store, getState)(): {});return Comp {...{ ...states1, ...dispatchs, ...rest }} /;}}/MyContext.Consumer);
};export default connect;
三 组件验证效果
1. Todo
import React from react;
import TodoInput from ./TodoInput;
import TodoList from ./TodoList;
import ContextProvider from ./ContextProvider;// 父组件
const Todo () {return (ContextProviderTodoInput /TodoList //ContextProvider);
};
export default Todo;
2. TodoList
import React, { useEffect } from react;
import TodoItem from ./TodoItem;
import _ from lodash;
import connect from ./connect;
import { mapStateTotProps } from ./mapStateToProps;
import { mapDispatchToProps } from ./mapDispatchToProps;
import styles from ./TodoList.scssconst TodoList (props) {const { todoList } props;console.log(styles, TodoList-styles, props)return (p className{styles.title}checckbox-list: /pdiv classNametodo-list{_.map(todoList, (item) (TodoItem key{_.get(item, id)} todo{item || {}} /))}/divhr //);
};export default connect(mapStateTotProps, mapDispatchToProps)(TodoList);
3.TodoItem
import _ from lodash;
import React from react;
import connect from ./connect;
import { mapStateTotProps } from ./mapStateToProps;
import { mapDispatchToProps } from ./mapDispatchToProps;// 孙子组件
const TodoItem (props: any) {const { todo, changeTodo } props;// 改变事项状态const handleChange () {changeTodo(_.get(todo, id));}return (div classNametodo-iteminput typecheckbox checked{todo.isFinished} onChange{handleChange} /span style{{ textDecoration: _.get(todo, isFinished) ? line-through : none }}{todo.text}/span/div)
}export default connect(mapStateTotProps, mapDispatchToProps)(TodoItem);
4.TodoInput
import React, { useState } from react;
import connect from ./connect;
import { mapStateTotProps } from ./mapStateToProps;
import { mapDispatchToProps } from ./mapDispatchToProps;
import styles from ./TodoInput.scss// 子组件
const TodoInput (props) {// console.log(styles, styles, props)const [text, setText] useState();const {addTodo,showAll,showFinished,showNotFinish,} props;const handleChangeText (e: React.ChangeEvent) {setText((e.target as HTMLInputElement).value);};const handleAddTodo () {if (!text) return;addTodo({id: new Date().getTime(),text: text,isFinished: false,});setText();};return (div className{styles[todo-input]}inputtypetextplaceholder请输入代办事项onChange{handleChangeText}value{text}classNameaaa/button className{styles.btn} onClick{handleAddTodo}添加/buttonbutton className{styles.btn} onClick{showAll}show all/buttonbutton className{styles.btn} onClick{showFinished}show finished/buttonbutton className{styles.btn} onClick{showNotFinish}show not finish/button/div);
};export default connect(mapStateTotProps, mapDispatchToProps)(TodoInput);
5. App组件引入Todo组件