Как получить доступ к конкретным элементам в массиве редукторов - PullRequest
0 голосов
/ 04 ноября 2019

Я хочу переключить свойство завершенного элемента нажатием. Проблема в том, что я понятия не имею, как это сделать в состоянии редуктора. Свойство хранится внутри объекта массивов, что затрудняет его поиск в редукторе.

App.js

import React,{ useReducer,useState } from 'react';
import logo from './logo.svg';
import './App.css';
import {reducer, initialState} from "./reducers/reducer"

function App() {
  const [item,setItem] = useState("")
  const [state,dispatch] = useReducer(reducer,initialState)
const handleCompleted = () => {
  dispatch({type:"TOGGLE_COMPLETED",payload:0})
  console.log(state[0])
}
const handleChanges = e => {
  setItem(e.target.value)
}
const addTodo = e => {
  dispatch({type:"ADD_TODO",newItem:{item:item,id:Date.now(),completed:false}})
  e.preventDefault()
  console.log(state)
}
  return (
    <form onSubmit={addTodo}>
      <button>submitTodo</button>
      <input onChange={handleChanges} value={item} />
      <div>
      <button onClick={handleCompleted}>completed</button>
      {state.list.map(i => <p key ={i.id}>{i.item}</p>)}
      </div>
    </form>
  );
}

export default App;

Reducer.js

export const initialState = {

        list :[{item: 'Learn about reducers',
        completed: false,
        id: 3892987589}]
}




export const reducer = (state,action) => {
    switch(action.type){
        case "TOGGLE_COMPLETED" : 
        return state.list[action.payload].completed = !state.list[action.payload].completed

        case "ADD_TODO" : 
        return {...state,list:[...state.list,action.newItem]}


        default:
            return state}

        }

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

вы можете использовать findIndex . В вашем случае используйте id, чтобы найти индекс в массиве, затем измените статус completed

.

const initialState = {

  list: [{
    item: 'Learn about reducers',
    completed: false,
    id: 3892987589
  }]
}



function changeStatus(id) {
  let getIndex = initialState.list.findIndex(e => e.id === id);
  initialState.list[getIndex].completed = true;
}

changeStatus(3892987589);
console.log(initialState.list)
0 голосов
/ 04 ноября 2019

Вы можете изменить функцию следующим образом в вашем App.js

const handleCompleted = (id) => {
  dispatch({type:"TOGGLE_COMPLETED",payload:id})
}

В функции рендеринга измените <button onClick={handleCompleted}>completed</button> на

{state.list.map(i => <p key ={i.id}>{i.item}<button onClick={this.handleCompleted.bind(this, i,id)}>completed</button></p>)}<button onClick={this.handleCompleted.bind(this, id)}>completed</button>

И в Reducers.js

Примечание. Обычно для удобства обновлений вам необходимо создать карту идентификаторов, соответствующих элементам. Но это также будет работать на данный момент.

export const reducer = (state,action) => {
    switch(action.type){
        case "TOGGLE_COMPLETED" : 
        const modifiedState = state.map(item=> {
          if(item.id === action.payload.id){
            return {
              ...item,
              completed: true
            }
          }
          return item
        });
        return modifiedState

        case "ADD_TODO" : 
        return {...state,list:[...state.list,action.newItem]}


        default:
            return state}

        }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...