Изменение state из внешней функции

Рейтинг: 0Ответов: 1Опубликовано: 24.06.2023

Делаю to do list, и мне нужно изменять количество выполненных задач когда галочка стоит, как мне сделать так что б изменялось количество этих выполненных задач в state?
файл toDoList

import React from 'react';
import Button from './Button'
import Tasks from './Tasks'
export default class ToDoList extends React.Component{
    constructor(props) {
        super(props);
        this.state={
            clicked:false,
            listArr: [{task:'Помыть посуду'}, {task:'сходить в магазин'},{task:'Сходить на работу'},{task:'сходить погулять'}],
        }
    }
 render(){

      return(
              <ol>
                  {this.state.listArr.map((taskE)=><li onChange={()=>{

                  }}><Tasks task={taskE.task}/></li>)}

                    <Button doneTasks={this.state.doneTask}/>

              </ol>

          )
    }
} 

файл tasks

import React from "react";

function Tasks({ task }) {
    return (
            <form>
                <input type="checkbox"  />
                <span>{task}</span>
            </form>
    );
}

export default Tasks;

Ответы

▲ 0

К сожалению, я не знаю что за компонент Button, поэтому заменил его на: Количество выполненных задач : {taskDone.length}. Вот сам код:

import React, { Component } from 'react';

export default class ToDoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      clicked: false,
      listArr: [
        { task: 'Помыть посуду' },
        { task: 'сходить в магазин' },
        { task: 'Сходить на работу' },
        { task: 'сходить погулять' }
      ],
      doneTask: []
    };
    this.handleTaskDone = this.handleTaskDone.bind(this);
  }

  handleTaskDone(task, isChecked) {
    const { doneTask, listArr } = this.state;
    if (isChecked == true) {
      this.setState({
        doneTask: doneTask.filter(l => l.task != task)
      });
    } else {
      this.setState({
        doneTask: [...doneTask, { task }]
      });
    }
  }

  render() {
    const { listArr, doneTask } = this.state;

    return (
      <ol>
        {listArr.map(taskE => (
          <li key={taskE.task}>
            <Tasks task={taskE.task} onDone={this.handleTaskDone} />
          </li>
        ))}
        Количество выполненных задач: {doneTask.length}
      </ol>
    );
  }
}

class Tasks extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isChecked: false
    };
    this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
  }

  handleCheckboxChange() {
    const { isChecked } = this.state;
    const { onDone, task } = this.props;
    this.setState({
      isChecked: !isChecked
    });
    onDone(task, isChecked);
  }

  render() {
    const { isChecked } = this.state;
    const { task } = this.props;

    return (
      <form>
        <input type="checkbox" checked={isChecked} onChange={this.handleCheckboxChange} />
        <span>{task}</span>
      </form>
    );
  }
}

А также код для тех, кто пишет на функциональных компонентах.

import React, { useState } from 'react';


export default function ToDoList() {
  const [clicked, setClicked] = useState(false);
  
  const [listArr, setListArr] = useState([
    { task: 'Помыть посуду' },
    { task: 'сходить в магазин' },
    { task: 'Сходить на работу' },
    { task: 'сходить погулять' }
  ]);
  const [doneTask,setDoneTask]=useState(listArr)

  function handleTaskDone(task,isChecked) {
    if(isChecked==true){
      setDoneTask(doneTask.filter(l=>{
      return l.task!=task
    }))
      
    }
    else{
      setDoneTask([...doneTask, {task}])
    }
    
  }

  return (
    <ol>
      {listArr.map((taskE) => (
        <li key={taskE.task}>
          <Tasks task={taskE.task} onDone={handleTaskDone} />
        </li>
      ))}
      Количество выполненных задач:  {listArr.length - doneTask.length}
    </ol>
  );
}


function Tasks({ task, onDone }) {
  const [isChecked, setIsChecked] = useState(false);

  function handleCheckboxChange() {
    setIsChecked(!isChecked);
    onDone(task,!isChecked);
  }

  return (
    <form>
      <input type="checkbox" checked={isChecked} onChange={handleCheckboxChange} />
      <span>{task}</span>
    </form>
  );
}