Después de de esta extensa recopilación de información solucionamos esta problema que suelen tener ciertos usuarios. Te brindamos la solución y esperamos que resulte de gran apoyo.
Solución:
Yo diría que esto significa que hacerlo de esta manera no es lo ideal. De hecho, la función depende de todos
. Si setTodos
se llama en otro lugar, la función de devolución de llamada debe volver a calcularse, de lo contrario, opera con datos obsoletos.
¿Por qué almacenas los ordenados? array en estado de todos modos? Puedes usar useMemo
para ordenar los valores cuando el key o la array cambios:
const sortedTodos = useMemo(() =>
return Array.from(todos).sort((a, b) =>
const v1 = a[sortKey].toLowerCase();
const v2 = b[sortKey].toLowerCase();
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
);
, [sortKey, todos]);
Entonces referencia sortedTodos
En todas partes.
Ejemplo en vivo:
const useState, useCallback, useMemo = React;
const exampleToDos = [
title: "This", priority: "1 - high", text: "Do this",
title: "That", priority: "1 - high", text: "Do that",
title: "The Other", priority: "2 - medium", text: "Do the other",
];
function Example()
const [sortKey, setSortKey] = useState('title');
const [todos, setTodos] = useState(exampleToDos);
const sortedTodos = useMemo(() =>
return Array.from(todos).sort((a, b) =>
const v1 = a[sortKey].toLowerCase();
const v2 = b[sortKey].toLowerCase();
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
);
, [sortKey, todos]);
const sortByChange = useCallback(e =>
setSortKey(e.target.value);
, []);
return (
Sort by:
sortedTodos.map((text, title, priority) => (
title priority
text
))
);
ReactDOM.render( , document.getElementById("root"));
body
font-family: sans-serif;
.todo
border: 1px solid #eee;
padding: 2px;
margin: 4px;
.todo h4
margin: 2px;
.priority
float: right;
No es necesario almacenar los valores ordenados en el estado, ya que siempre puede derivar/calcular los valores ordenados array de la “base” array y el tipo key. Yo diría que también hace que su código sea más fácil de entender ya que es menos complejo.
El motivo del bucle infinito es que todos no coincide con la referencia anterior y el efecto se volverá a ejecutar.
¿Por qué usar un efecto para una acción de clic de todos modos? Puedes ejecutarlo en una función como esta:
const [todos, setTodos] = useState([]);
function sortTodos(e)
const sortKey = e.target.value;
const clonedTodos = [...todos];
const sorted = clonedTodos.sort((a, b) =>
return a[sortKey.toLowerCase()].localeCompare(b[sortKey.toLowerCase()]);
);
setTodos(sorted);
y en tu menú desplegable haz un onChange
.
Por cierto, tenga en cuenta la dependencia, ¡ESLint tiene razón! Tus Todos, en el caso descrito anteriormente, son una dependencia y deberían estar en la lista. El enfoque sobre la selección de un elemento es incorrecto y, por lo tanto, su problema.
Comentarios y calificaciones del tutorial
Más adelante puedes encontrar las anotaciones de otros administradores, tú igualmente tienes la opción de insertar el tuyo si te gusta.