Redux, как отфильтровать таски
Как отфильтровать таски, и при нажатии на кнопки DONE, ACTIVE, ALL показывать соответствующие им таски? Использую connect для передачи пропсов.
import React from 'react'
import shortid from 'shortid';
const ADD_TASK = 'ADD_TASK'
const EDIT_STATUS = 'EDIT_STATUS'
const TASK_DELETE = 'TASK_DELETE'
const SHOW_ALL = 'SHOW_ALL'
const SHOW_ACTIVE = 'SHOW_ACTIVE'
const SHOW_DONE = 'SHOW_DONE'
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 SHOW_DONE: {
return {
}
}
case SHOW_ACTIVE: {
return {
}
}
default:
return state
}
}
export const showAll = () => ({type: 'SHOW_ALL'})
export const showActive = () => ({type: 'SHOW_ACTIVE'})
export const showDone = () => ({type: 'SHOW_DONE'})
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 default mainReducer;
import React from "react";
import s from "./../../App.module.css";
import Item from "./item"
import CurrentTasks from "../current-tasks";
class SetForm extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ''
}
}
onInputChange = event => {
this.setState({
[event.target.name]: event.target.value
})
}
handleSubmit = event => {
event.preventDefault();
if(this.state.text === '') {
return undefined
}
this.props.addTask(this.state.text)
this.setState({
text: ''
})
}
render() {
const filterTasks = (tasks, activeFilter) => {
switch (activeFilter) {
case 'done': {
return tasks.filter(task => task.status);
}
case 'active': {
return tasks.filter(task => !task.status)
}
default:
return tasks;
}
};
const currentTasks = filterTasks(this.props.tasks, this.props.filterReducer);
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<input
name={"text"}
onChange={this.onInputChange}
value={this.state.text}
placeholder={"Set your task"}
className={s.setTask}
/>
<button onClick={this.handleSubmit} className={s.add}>ADD</button>
</div>
</form>
<CurrentTasks tasks={this.props.tasks}/>
{this.currentTasks}
{this.props.tasks.map(t => (<Item editStatus={() => this.props.editStatus(t.id)}
deleteTask={() => this.props.deleteTask(t.id)}
key={t.id} task={t.task} status={t.status}/>))}
{/* <FilterButtonTasks tasks={this.props.tasks} /> */}
<button onClick={() => this.props.changeFilter('all')}> all </button>
<button onClick={() =>this.props.changeFilter('done')}> done</button>
<button onClick={() =>this.props.changeFilter('active')}> active</button>
</div>
)
}
}
export default SetForm;
import React from 'react'
import SetForm from './set-item'
import { compose } from 'redux'
import { addTask, editStatus, deleteTask,changeFilter} from '../../redux/main-reducer';
import { connect } from 'react-redux';
export class SetFormContainer extends React.Component {
render(){
return (
<SetForm />
)
}
}
const mapStateToProps = (state) => {
return {
tasks: state.mainReducer.tasks,
filter: state.filtersReducer
}
}
export default compose(connect(mapStateToProps,{editStatus ,addTask,deleteTask,changeFilter}))(SetForm)
Ответы (1 шт):
Автор решения: 1ocke
→ Ссылка
Файл с редьюсерами.
import React from 'react';
import { combineReducers } from 'redux';
import shortid from 'shortid';
const ADD_TASK = 'ADD_TASK';
const EDIT_STATUS = 'EDIT_STATUS';
const TASK_DELETE = 'TASK_DELETE';
const CHANGE_FILTER = 'CHANGE_FILTER';
const baseFilter = 'all';
const initialState = {
tasks: []
};
const tasksReducer = (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)
}
}
default:
return state
}
}
const filtersReducer = (state = baseFilter, action) => {
switch (action.type) {
case CHANGE_FILTER: {
return action.activeFilter;
}
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 changeFilter = activeFilter => ({type: CHANGE_FILTER, activeFilter})
const mainReducer = combineReducers({tasksReducer, filtersReducer})
export default mainReducer;
После в нашем компоненте вытаскиваем из пропсов filtersReducer, где хранится название нашего фильтра (по-умолчанию 'all'). И экшен changeFilter, который вешаем на кнопки с соответсвующим аргументом.
А также создаем в компоненте функцию фильтрации тасков, куда передаем таски и наш filtersReducer.
Файл с компонентом.
import React from "react";
import s from "./../../App.module.css";
import Item from "./item"
import CurrentTasks from "../current-tasks";
class SetForm extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ''
}
}
onInputChange = event => {
this.setState({
[event.target.name]: event.target.value
})
}
handleSubmit = event => {
event.preventDefault();
if(this.state.text === '') {
return undefined
}
this.props.addTask(this.state.text)
this.setState({
text: ''
})
}
filterTasks = (tasks, activeFilter) => {
switch (activeFilter) {
case 'done': {
return tasks.filter(task => task.status);
}
case 'active': {
return tasks.filter(task => !task.status)
}
default:
return tasks;
}
}
render() {
const currentTasks = this.filterTasks(this.props.tasks, this.props.filter);
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<input
name={"text"}
onChange={this.onInputChange}
value={this.state.text}
placeholder={"Set your task"}
className={s.setTask}
/>
<button onClick={this.handleSubmit} className={s.add}>ADD</button>
</div>
</form>
<CurrentTasks tasks={this.props.tasks}/>
{currentTasks.map(t => (<Item editStatus={() => this.props.editStatus(t.id)}
deleteTask={() => this.props.deleteTask(t.id)}
key={t.id} task={t.task} status={t.status}/>))}
{/* <FilterButtonTasks tasks={this.props.tasks} /> */}
<button onClick={() => this.props.changeFilter('all')}> all </button>
<button onClick={() =>this.props.changeFilter('done')}> done</button>
<button onClick={() =>this.props.changeFilter('active')}> active</button>
</div>
)
}
}
export default SetForm;