React-Redux, как изменить состояние? - PullRequest
0 голосов
/ 22 апреля 2020

У меня такая проблема: я делаю To-Do-List, и теперь я хочу сделать EditMode для своих задач. Но когда я пытаюсь это сделать, он возвращает строку, а не массив, и поэтому у меня 3 ошибки (map, some, filter = не является функцией). Поэтому я не знаю, как изменить состояние (задачу) и вернуть измененный массив.

Некоторые детали: я использую connect для получения реквизита.

Код компонента

class Item extends React.Component {
    state = {
        statusChange: false,
        task: ''
    }

    activeStatusChange = () => {
        this.setState( {
            statusChange: true
           }
       );        
    }

    deActivateStatusChange = () => {
        this.setState( {
            statusChange: false
           }
       );      
       this.props.editTask(this.state.task)
    }

    onStatusChange = (e) => {
        this.setState({
            task: e.currentTarget.value
        })
    }


    render(){
        return (
            <div className={s.item}>
            <span onClick={this.props.editStatus} className={s.statusTask}>
                {this.props.status  ? <img src="https://img.icons8.com/doodle/48/000000/checkmark.png"/> 
                                    : <img src="https://img.icons8.com/emoji/48/000000/red-circle-emoji.png"/>}
            </span>

            { this.state.statusChange 
                ? <input onChange={this.onStatusChange} autoFocus={true} onBlur={this.deActivateStatusChange} value={this.state.task} /> 
                : <span  className={this.props.status === true ? s.task : s.taskFalse} onClick={this.activeStatusChange}> {this.props.task} </span>}

            <span onClick={this.props.deleteTask} className={s.close}><img src="https://img.icons8.com/color/48/000000/close-window.png"/></span>

        </div>
        )
    }
}

export default Item;


Код редуктора

import React from 'react'
import shortid from 'shortid';

const ADD_TASK = 'ADD_TASK'
const EDIT_STATUS = 'EDIT_STATUS'
const TASK_DELETE = 'TASK_DELETE'
const REMOVE_ALL_DONE = 'REMOVE_ALL_DONE'
const REMOVE_ALL_TASKS = 'REMOVE_ALL_TASKS'
const EDIT_TASK = 'EDIT_TASK'

const initialState = {
    tasks: []
};



const mainReducer = (state = initialState, action) => {
    switch (action.type) {

        case ADD_TASK: {
            return {
                ...state,
                tasks: [{
                    id: shortid.generate(),
                    task: action.task,
                    status: false
                }, ...state.tasks]
            }
        }

        case EDIT_STATUS: {
            return {
                ...state,
                tasks: state.tasks.map(task => task.id === action.id ? {...task, status: !task.status} : task)
            }
        }

        case TASK_DELETE: {
            return {
                ...state,
                tasks: state.tasks.filter(t => t.id !== action.id)
            }
        }

        case REMOVE_ALL_DONE: {
            return {
                ...state,
                tasks: state.tasks.filter(t => !t.status)
            }
        }

        case REMOVE_ALL_TASKS: {
            return {
                ...state,
                tasks: []
            }
        }

        case EDIT_TASK: {
            return {
                ...state,
                tasks: action.task
            }
        }

    default:
        return state
    }
}


export const addTask = task => ({type: 'ADD_TASK', task});
export const editStatus = id => ({type: 'EDIT_STATUS', id})
export const deleteTask = id => ({type: 'TASK_DELETE', id})
export const removeAllDone = () => ({type:'REMOVE_ALL_DONE'})
export const removeAllTasks = () => ({type: 'REMOVE_ALL_TASKS'})
export const editTask = task => ({type: 'EDIT_TASK', task})


export default mainReducer;

1 Ответ

0 голосов
/ 22 апреля 2020

Вы должны создать контейнер, который использует методы mapDispatchToProps, чтобы вы могли использовать свои действия в компоненте.

https://react-redux.js.org/using-react-redux/connect-mapdispatch

Итак, давайте сделаем это. Просто создайте файл, который будет вашим контейнером для этого компонента, и поместите код следующим образом:

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import Item from 'wherever your component is';
import { addTask } from 'wherever your action is';


const mapStateToProps = ({  }) => ({
    // Here you can pass the redu state to your component
});

const mapDispatchToProps = (dispatch) => ({
  ...bindActionCreators({
      // Here you pass the action to your component
      addTask
  }, dispatch)
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(Item);

Затем, когда вы захотите использовать компонент Item, импортируйте его из контейнера, и он получит в подпорках как действие и состояние, которое вы передаете из файла контейнера.

В компоненте «Вы» вы можете использовать такое действие:

// ITem component
render() {
    return (
        <button onClick={this.props.addTask} />
    )
}

Если есть сомнения, просто дайте мне знать!

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