DEV Community

Dennis Zhang
Dennis Zhang

Posted on

redux的使用

1、安装 npm install @reduxjs/toolkit react-redux

然后在创建reducer,传入配置configureStore({reducer:对象,})

// store.js
import { configureStore, createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import thunkMiddleware from 'redux-thunk';

// 创建一个初始状态
const initialState = {
  todos: [],
};
// 创建一个异步 action 
export const fetchTodos = createAsyncThunk('todos/fetchTodos', 
    async () => { 
        const response = await fetch('/api/todos'); 
        const data = await response.json(); 
        return data; 
        }
   );

// 创建一个 slice
export const {
  reducer:todosReducer,
  actions:{
    addTodo,
    toggleTodo,
  }
} = createSlice({
  name: 'todos',
  initialState,
  reducers: {
    addTodo: (state, action) => {
      state.todos.push(action.payload);
    },
    toggleTodo: (state, action) => {
      const todo = state.todos.find(todo => todo.id === action.payload);
      if (todo) {
        todo.completed = !todo.completed;
      }
    },
  },
  extraReducers: { 
  // 处理异步 action 的 pending、fulfilled、rejected 状态 
  [fetchTodos.pending]: (state) => { 
      state.status = 'loading';
  }, 
  [fetchTodos.fulfilled]: (state, action) => { 
      state.status = 'idle';
      state.todos = action.payload;
  }, 
  [fetchTodos.rejected]: (state, action) => { 
      state.status = 'error';
      state.error = action.error.message; 
  }, },
});

// 创建 store, 多个reducer
const rootReducer = { 
    todos: todosReducer, 
    visibilityFilter: visibilityFilterSlice.reducer, 
  }

export default configureStore({
  reducer: rootReducer,
  middleware:(getDefaultMiddleware)=>getDefaultMiddleware().concat(thunkMiddleware),
});

Enter fullscreen mode Exit fullscreen mode

2、要在根组件引用

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Enter fullscreen mode Exit fullscreen mode

3、组件中触发使用

// App.js
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { v4 as uuid } from 'uuid';
import { addTodo, toggleTodo, deleteTodo } from './store';

function App() {
  const [text, setText] = useState('');
  const dispatch = useDispatch();
  const todos = useSelector(state => state.todos);

  const handleAddTodo = () => {
    if (text.trim() !== '') {
      dispatch(addTodo({
        id: uuid(),
        text,
        completed: false,
      }));
      setText('');
    }
  };

  const handleToggleTodo = id => {
    dispatch(toggleTodo(id));
  };

  const handleDeleteTodo = id => {
    dispatch(deleteTodo(id));
  };

  return (
    <div>
      <h1>Todo List</h1>
      <input
        type="text"
        value={text}
        onChange={e => setText(e.target.value)}
        placeholder="Add Todo"
      />
      <button onClick={handleAddTodo}>Add</button>
      <ul>
        {todos.map(todo => (
          <li
            key={todo.id}
            style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
            onClick={() => handleToggleTodo(todo.id)}
          >
            {todo.text}
            <button onClick={() => handleDeleteTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

Top comments (0)