如何使用功能组件从 Redux 存储中检索数据并避免 useSelector & useDispatch

时间:2021-07-15 22:41:53

标签: javascript reactjs redux state mapstatetoprops

我正在 React-Redux 中尝试使用 Todo 应用程序;运行 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;

App.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;

Home.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)     

2 个答案:

答案 0 :(得分:1)

您正在寻找 useSelector 钩子。

不要在函数组件中使用 store.getState()。此外,您不需要 connect 函数组件,使用 useDispatch 钩子。

从商店获取值将是这样的:

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

答案 1 :(得分:1)

很奇怪,他们(代码训练营)要求你使用函数组件,然后不允许你使用使函数组件如此吸引人的 React 钩子。不用担心,您仍然可以使用旧的 connect 高阶组件将您的 redux 状态和可调度操作注入传递给组件的 props。

您在 AddToDo 组件中遇到问题。您将 mapDispatchToProps 传递给 connect HOC,mapStateToProps 回调将在其中传递。您也没有使用刚刚映射的注入 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 组件中,您的待办事项状态是一个数组,因此您可能希望将其映射到 JSX。记住要解构传递的道具。由于您没有分享您的减速器或您如何组合减速器,我将假设 todos 位于状态根目录下只有一个减速器。

[更新] 由于您的 rootReducer 似乎只是您的 todos 减速器函数,而且我看不到 combineReducers 在哪里用于构建更复杂的状态树,state < strong>IS 您试图传递给 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);
相关问题