- 引入 Provider 并包裹APP 入口文件,方便在每个页面都可以使用redux
import { Provider } from 'react-redux'
import store from './store'
// 渲染根组件App 到一个id为root 的dom 节点上
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
)
- store/indexjs 文件
import { configureStore } from '@reduxjs/toolkit'
import todos from './tode'
const store = configureStore({
reducer: {
todos
}
})
export default store
- todosjs 文件
import { createSlice } from '@reduxjs/toolkit'
const initialState = []
const todoSlice = createSlice({
name: 'todos',
initialState,
reducers: {
addTodo: (state,action) => {
const { id, text} = action.payload
state.push({ id, text, completed: false })
},
removeTodo: (state, action) => {
return state.filter(todo => todo.id !== action.payload)
},
toggleTodo: (state, action) => {
const index = state.findIndex(tode => tode.id === action.payload)
if (index !== -1) {
state[index].completed = !state[index].completed
}
}
}
})
export const { addTodo, removeTodo, toggleTodo } = todoSlice.actions
export default todoSlice.reducer
- 组件中使用 todoList.js
import React, { useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { addTodo, removeTodo, toggleTodo } from '../../store/todos'
export default function TodoList() {
const [inputValue, setInputValue] = useState('')
const todos = useSelector(state => state.todos)
const dispatch = useDispatch()
const handleAdd = () => {
dispatch(addTodo({
id: Date.now(),
text: inputValue
}))
setInputValue('')
}
const handleDel = (id) => {
dispatch(removeTodo(id))
}
const handleToggle = (id) => {
dispatch(toggleTodo(id))
}
return (
<div>
<input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
<button onClick={handleAdd}>Add</button>
<ul>
{
todos.map(todo => (
<li
key={todo.id}
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
onClick={ () => handleToggle(todo.id) }
>
{ todo.text }
<button onClick={() => handleDel(todo.id)}>Delete</button>
</li>
))
}
</ul>
</div>
)
}