簡體   English   中英

如何使用功能組件從 Redux 存儲中檢索數據並避免 useSelector 和 useDispatch

[英]How to retrieve data from Redux store using functional components and avoiding useSelector & useDispatch

我正在 React-Redux 中嘗試使用 Todo App; 運行 store、actions、reducer 和 Addodo 組件; 但一直堅持顯示待辦事項:

如果我的 initialState=[] 如何從商店檢索數據?

店鋪:

import { createStore } from 'redux';
import rootReducer from '../reducer';

export const store = createStore(
  rootReducer, 
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  );

 export default store

我的減速機:

const initialState = [];


const todos = (state = initialState, action) => {
  switch(action.type) {
    // Aca va tu codigo;    
      case 'AddTodo':     
        return [...state, action.payload]; 
        
      case 'RemoveTodo':
        return state.filter(todo => todo.id  !== action.payload)
        
      case 'ToInProgress':             
        return state.map((todo) =>
          todo.id === action.payload ? { ...todo, status: "InProgress" } : todo
        ); 
                     
        case 'ToDone':
         return state.map((todo) =>
          todo.id === action.payload ? { ...todo, status: "Done" } : todo
        );
       
        default: 
        return state
      }
    }
      
 export default todos;

應用程序.js:

import React from 'react'
import { Route } from "react-router-dom"
import {Provider} from 'react-redux'
import store from './store/index'

import Nav from '../src/components/Nav/Nav'
import Home from '../src/components/Home/Home'
import AddTodo from '../src/components/AddTodo/AddTodo'
import TodoDetail from '../src/components/TodoDetail/TodoDetail'
import './App.css';

export function App() {
  return (
    <React.Fragment>
      <Provider store={store}>
        <Nav />
        <Route exact path="/" component={Home} />
        <Route path="/add" component={AddTodo} />
        <Route path="/edit/:id" component={TodoDetail} />
      </Provider>
    </React.Fragment>
  );
}

export default App;

主頁.js:

import React from 'react';
import Todos from '../Todos/Todos'
import './home.css'

export function Home() {
  return (
  
    <div className="todosContainer"> 
    <div>
      <Todos status="Todo"/>
      <label>TODO</label>
    </div>
    <div>
      <Todos status='InProgress' />
      <label>InProgress</label>
    </div>
    <div>
      <Todos status='Done'/>
      <label>Done</label>
    </div>
    </div>
  )
};     

export default Home;

這是 AddTodo:

export function AddTodo() {
   const [state,setState]=React.useState({
     title:"",
     description:"",
     place:"",
     date:"",
   })

  function handleChange(e){ 
    const value=e.target.value;
    setState({
      ...state,
      [e.target.name]:value
    })
  }

  function handleSubmit(e){
    e.preventDefault();
    store.dispatch(addTodo({
      place:state.place,
      title:state.title,
      date:state.date,
      description:state.description
    })) // parameters "id" & "status" loaded in Actions.
    setState({title:"",
    description:"",
    place:"",
    date:"",})
  }

  return (
    <div className="todoContainer">
      <form id="formulario"onSubmit={handleSubmit} >
        <label>
          Title
          <input type="text" name="title" value={state.title} onChange={handleChange} />
        </label>
        <label>
          Description
          <textarea type="text" name="description" value={state.description} onChange= {handleChange}/>
        </label>
        <label>
          Place
          <input type="text" name="place" value={state.place} onChange={handleChange}/>
        </label>
        <label>
          Date
          <input type="text" name="date" value={state.date} onChange={handleChange}/>
        </label>
        <button className="boton" type="submit" onClick={addTodo}>Agregar</button>
      </form>
    </div>
  )
};

function mapDispatchToProps(dispatch){
  return{
    addTodo: todo => dispatch(addTodo(todo))
  }
}

export default connect(mapDispatchToProps)(AddTodo)

現在,我想在 Todos 組件中展示,每個 Todos “標題”,仍然不知道如何執行它:

export function Todos(data) {
  
  return (
    <div className="todoDetail">

        <h4>{data.title}</h4>  
    </div>
  )
};
  
function mapStateToProps(state) {
  return {
    data: state.title,   
  };
  
}   
export default connect(mapStateToProps)(Todos)     

你在找useSelector鈎子。

不要在功能組件中使用store.getState() 此外,您不需要connect功能組件,使用useDispatch鈎子。

從商店獲取值將是這樣的:

const todos = useSelector(store => store.items);

很奇怪,他們(代碼訓練營)要求你使用函數組件,然后不允許你使用 React 鈎子,使函數組件如此吸引人。 不用擔心,您仍然可以使用舊的connect高階組件將您的 redux 狀態和可調度操作注入傳遞給組件的 props。

您在AddToDo組件中AddToDo問題。 您將mapDispatchToProps傳遞到將傳遞mapStateToProps回調的connect HOC。 您也沒有使用剛剛映射的注入的addTodo操作。 你幾乎不需要直接訪問store對象來分派動作,使用 React 組件/鈎子。

export function AddTodo() {
  const [state, setState] = React.useState({
    title:"",
    description:"",
    place:"",
    date:"",
  });

  function handleChange(e) { 
    const { value } = e.target;
    setState(prevState => ({ // <-- use functional state update
      ...prevState,
      [e.target.name]:value
    }));
  }

  function handleSubmit(e) {
    e.preventDefault();
    this.props.addTodo({ // <-- addTodo action injected into props
      place:state.place,
      title:state.title,
      date:state.date,
      description:state.description
    });
    setState({
      title:"",
      description:"",
      place:"",
      date:"",
    });
  }

  return (
    <div className="todoContainer">
      ...
    </div>
  )
};

const mapDispatchToProps = {
  addTodo,
}

export default connect(null, mapDispatchToProps)(AddTodo); // <-- mapStateToProps is null

Todos組件中,您的 todos 狀態是一個數組,因此您可能希望將其映射到 JSX。 記住要解構傳遞的道具。 由於您沒有共享您的減速器或您如何組合減速器,我將假設只有一個用於位於狀態根的todos減速器。

[更新] 由於您的rootReducer似乎只是您的todos reducer 函數,而且我沒有看到combineReducers用於構建更復雜的狀態樹的位置,因此state您嘗試傳遞給Todos組件的todos數組狀態。 [/更新]

function Todos({ todos }) {
  return (
    <div className="todoDetail">
      {todos.map((todo) => (
        <h4 key={todo.id}>{todo.title}</h4>
      ))}  
    </div>
  )
};
  
function mapStateToProps(state) {
  return {
    todos: state, // <-- state is todos array
  };
}

export default connect(mapStateToProps)(Todos);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM