2
respostas

React Component não é renderizado novamente após alterado o respectivo estado.

Oi! To criando um gerenciador de tarefas, mas travei num problema. Eu quero habilitar e desabilitar a tarefa ao clicar na respectiva checkbox. Por algum motivo a alteração do estado só ocorre nos primeiros dois clicks sobre a checkbox e o componente da tarefa em si não é re-renderizado. O que pode ser? Abaixo deixo um vídeo e o código para melhor exemplificar o problema.

https://www.youtube.com/watch?v=OytdpgGBWho

const TodoItem = ({todo, todoIndex, updateTodo}) => {
  const {title, body, tag, isDisabled} = todo;

  // Habilita ou desabilita a tarefa
  function changeTodoStatusHandler() {
    updateTodo(todoList => {
      todoList[todoIndex].isDisabled = !isDisabled;
      return todoList;
    })
  }

  return (
    <TodoItemStyled>
      <input type="text" defaultValue={title} disabled={!isDisabled ? false : true}/>
      <textarea defaultValue={body} disabled={!isDisabled ? false : true}></textarea>
      {!tag && !isDisabled && <select></select>}
      <label htmlFor='status'>
       <input type='checkbox' id='status' onChange={() => changeTodoStatusHandler()}/>
        {!isDisabled ? 'Feito' : 'Editar'}
      </label>
    </TodoItemStyled>
  );
}
2 respostas

Oi Leonardo!

Você poderia postar o código completo para que eu possa analisar melhor?

Aguardo seu retorno!

Oi, Eduardo! Alterei algumas coisas, porém o problema persiste.

Vou tentar colocar o código dos components que imagino que estejam relacionados ao problema.

De qualquer forma deixo o link do repositório também. É esse AQUI. Os componentes encontram-se no path src > components

App.js

import React, { useState } from 'react';

// COMPONENTS
import { Helmet } from 'react-helmet';
import SmoothReset from '@Global/components/SmoothReset';
import Grid from '@Components/Grid';
import TodoHeader from '@Components/TodoHeader/TodoHeader';
import TodoAside from '@Components/TodoAside/TodoAside';
import TodoMain from '@Components/TodoMain/TodoMain';

// VARIABLES
import { fontSize as fs} from '@Global/variables/font_size.js';

// UTILS
import { v4 as uuidv4 } from 'uuid';

const App = () => {
  // Lista de tags
  const [ tagsList, setTagsList ] = useState([]);
  // Lista de tarefas
  const [ todoList, setTodoList] = useState([]);

  const disableTodoHandler = (todoIndex, todoStatus) => {
    setTodoList(todoList => {
      todoList[todoIndex].status = !todoStatus;
      return todoList;
    });
  };

  return (
    <>
      <Helmet>
        <meta charSet="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>React - Task Manager</title>
      </Helmet>
      <SmoothReset fontSize={fs}/>
      <Grid>
        <TodoHeader addNewTodo={setTodoList}/>
        <TodoAside tagsList={tagsList} updateTagsList={setTagsList}/>
        {
          todoList.length !== 0 
          &&
          <TodoMain todoList={todoList} idBuilder={uuidv4} onDisableTodo={disableTodoHandler}/>
        }
      </Grid>
    </>
  )
}

export default App;

TodoHeader.js

import React from 'react';
import styled from 'styled-components';

// COMPONENTS
const TodoHeaderStyled = styled.header`
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  a {
    font-size: 2rem;
  }
  button {
    padding: .6rem 1rem;
    border: 1px solid grey;
  }
`
const TodoHeader = ({ addNewTodo }) => {
  function addNewTodoHandler() {
    const newTodo = { title:'', body: '', tag:'', status: true }
    addNewTodo(todoList => [...todoList, newTodo])
  }

  return (
    <TodoHeaderStyled>
      <a href="#">
        <h1>To Do</h1>
      </a>
      <button onClick={addNewTodoHandler}>Add task</button>
    </TodoHeaderStyled>
  );
}

export default TodoHeader;

TodoMain.js

import React from 'react';
import styled from 'styled-components';

// COMPONENTS
import TodoItem from '@Components/TodoMain/TodoItem';

const TodoMainStyled = styled.main`
  grid-column: 1 / -1;
`;

const TodoList = styled.ul`
`;

const TodoMain = ({todoList, idBuilder, onDisableTodo}) => {
  return (
    <TodoMainStyled>
      <TodoList>
        {todoList.map((todo, index) => {
          const {title, body, tag, status} = todo
          return (
            <TodoItem 
              key={idBuilder()} 
              title={title}
              body={body}
              tag={tag}
              todoStatus={status}
              todoIndex={index} 
              onDisable={onDisableTodo}
            />
          )
        })}
      </TodoList>
    </TodoMainStyled>
  );
}

export default TodoMain;

TodoItem.js

import React from 'react';
import styled from 'styled-components';

const TodoItemStyled = styled.li`
  padding: .8rem;
  border: 1px solid grey;
`;

const TodoItem = ({title, body, tag, todoStatus, todoIndex, onDisable}) => {
  // Habilita ou desabilita a tarefa
  function disableHandler() {
    onDisable(todoIndex, todoStatus);
  }

  return (
    <TodoItemStyled>
      <input type="text" defaultValue={title} disabled={!todoStatus}/>
      <textarea defaultValue={body} disabled={!todoStatus}></textarea>
      {tag && !todoStatus && <select></select>}
      <button onClick={disableHandler}>
        {!todoStatus ? 'Editar' : 'Feito'}
      </button>
    </TodoItemStyled>
  );
}

export default TodoItem;

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software