博主在学习React Hook的时候遇到了一些坑,比如整合 redux 的时候,网上的方案大多不可用,要么就是过时了,踩了很多坑,最后终于实现了。特写了一篇博客记录下来。避免再次踩坑。
首先创建一个React+TypeScript 的项目,根据 官方文档 的说明,目前为止最新的创建方法为:
npx create-react-app my-app --template typescript
然后删除不必要的文件及index.html
中不必要的代码(非强制,可删可不删),然后创建一些文件,最终使项目目录结构如下:
npm install redux --save
npm install redux-react-hook --save
npm install antd --save
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
import {
CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM} from './actionTypes';
export const getInputChangeAction = (value: string) => {
return {
type: CHANGE_INPUT_VALUE,
value
}
}
export const getAddItemAction = () => {
return {
type: ADD_TODO_ITEM
}
}
export const getDeleteItemAction = (index: number) => {
return {
type: DELETE_TODO_ITEM,
index
}
}
import {
CHANGE_INPUT_VALUE, DELETE_TODO_ITEM, ADD_TODO_ITEM} from './actionTypes';
interface MyState {
inputValue: string,
list: string[]
}
const defaultState: MyState = {
inputValue: '',
list: []
}
export default (state: MyState = defaultState, action: any) => {
const newState: MyState = JSON.parse(JSON.stringify(state));
if (action.type === CHANGE_INPUT_VALUE) {
newState.inputValue = action.value;
return newState;
}
if (action.type === ADD_TODO_ITEM) {
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState;
}
if (action.type === DELETE_TODO_ITEM) {
newState.list.splice(action.index, 1);
return newState
}
return state;
}
import {
createStore} from 'redux';
import reducer from "./reducer";
const store = createStore(reducer);
export default store;
.parent{
margin: 20px;
}
#itemInput{
width: 300px;
margin-right: 20px;
}
#list{
margin-top: 15px;
width: 300px;
}
import React, {
useEffect, Fragment} from 'react';
import {
List, Input, Button} from 'antd';
import './App.css';
import {
useMappedState, useDispatch} from "redux-react-hook";
import {
getInputChangeAction,
getAddItemAction,
getDeleteItemAction
} from './store/actionCreators';
const App = () => {
const inputValue = useMappedState<string>(state => state.inputValue);
const list = useMappedState(state => state.list);
const dispatch = useDispatch();
useEffect(() => {
console.log('success');
})
const handleButtonClick = () => {
const action = getAddItemAction();
dispatch(action);
}
const handleItemDelete = (index: number) => {
const action = getDeleteItemAction(index);
dispatch(action);
}
const handleInputValueChange = (e: any) => {
const action = getInputChangeAction(e.target.value);
dispatch(action);
}
return (
<Fragment>
<div className='parent'>
<div>
<Input id='itemInput' value={
inputValue} placeholder='请输入内容'
onChange={
(e) => {
handleInputValueChange(e)
}}
/>
<Button type='primary' onClick={
handleButtonClick}>提交</Button>
</div>
<List id='list' size="small" bordered dataSource={
list}
renderItem={
(item: string, index: number) => {
return (
<List.Item onClick={
() => handleItemDelete(index)} title='点击删除'>
{
item}
</List.Item>
)
}}
/>
</div>
</Fragment>
)
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import {
StoreContext} from "redux-react-hook";
import store from "./store";
import App from "./App";
ReactDOM.render(
<StoreContext.Provider value={
store}>
<App/>
</StoreContext.Provider>,
document.getElementById('root')
);
npm start
效果如下
这就是React+Hook+Redux+Ant-d+TypeScript实现的TodoList功能