Как обновить только выбранный компонент с реагирующими хуками - PullRequest
1 голос
/ 09 июля 2019

Я кодирую список дел с помощью перехватчиков React. Каждый добавленный элемент имеет два раскрывающихся списка, в которых пользователь может решить, насколько срочна задача (значение срочности) и сколько времени займет выполнение задачи (значение скорости). Обновление любого списка добавит их значение в свойство «Score».

Нажав кнопку «Сортировка», я могу отсортировать записи по баллам.

В настоящее время проблема заключается в том, что если у меня есть более одного элемента с разными срочностью и значением скорости, оценка всегда будет одинаковой для обоих компонентов.

Может кто-нибудь помочь? Спасибо

function ToDo(){
  const [ input, setInput ] = React.useState('')
  const [ toDo, setToDo ] = React.useState([])
  const [ score, setScore ] = React.useState(0)
  const [ speed, setSpeed ] = React.useState(0)
  const [ urgency, setUrgency ] = React.useState(0)

  return(
    <div>
      <h2>List of things to do</h2>
      <input
          value={ input }
          onChange={ (e) => setInput( e.target.value ) }/>
      <button 
        onClick={ () => {
          setToDo( toDo.concat(input))
          setInput('')
          }}>Add
      </button>
      <ul>
        { toDo.map(( task, idTask ) => {
          return (
            <li 
              key={idTask}
              score={ speed + urgency }>
              {task}<br/>
              <select onChange={(e) => { setSpeed(Number(e.target.value)) }}>
                <option value={1}>slow</option>
                <option value={2}>medium</option>
                <option value={3}>fast</option>
              </select><br/>
              <select onChange={(e) => { setUrgency(Number(e.target.value)) }}>
                <option value={1}>non-urgent</option>
                <option value={3}>urgent</option>
              </select>
              <span 
                onClick={ 
                  (index) => {
                    const newTodos = [...toDo]
                    newTodos.splice(index, 1);
                    setToDo( newTodos)
                  }}>
                [-------]
              </span>
            </li>
            )
          })
         }
      </ul>
      <button onClick={ 
          () => { 
            const sortMe = [...toDo].sort((a, b) => b - a)
            setToDo( sortMe )
          }}>Sort!</button>
    </div>
    )
  }

ReactDOM.render(<ToDo/>, document.getElementById('app'));

1 Ответ

0 голосов
/ 09 июля 2019

Вы должны реализовать другую модель данных для достижения этой цели.Вы должны хранить массив объектов для вашего todos (каждый todo будет объектом), и каждый объект должен иметь свойство urgency, чтобы вы могли установить его индивидуально.

Примерно так:

function App() {

  const [todos,setTodos] = React.useState([
    { id: 'todo1', text: 'This is todo1', urgency: 0 },
    { id: 'todo2', text: 'This is todo2', urgency: 1 }
  ]);
  
  function handleClick(id) {
    setTodos((prevState) => {
      let aux = Array.from(prevState);
      aux = aux.map((todo) => {
        if (todo.id === id) {
          todo.urgency === 0 ? todo.urgency = 1 : todo.urgency = 0;
        }
        return todo;
      });
      return aux;
    });
  }
  
  const todoItems = todos.map((todo) => 
    <li 
      key={todo.id}
      className={todo.urgency === 1 ? 'urgent' : 'normal'}
      onClick={()=>handleClick(todo.id)}
    >
      {todo.text}
      {!!todo.urgency && '<--- This is urgent'}
    </li>
  );

  return(
    <React.Fragment>
      <div>
        Click on the todos!
      </div>
      <ul>
        {todoItems}
      </ul>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
li {
  cursor: pointer;
}

.urgent {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>

<div id="root"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...