#javascript #reactjs
#javascript #reactjs
Вопрос:
Не могли бы вы помочь мне с этим, пожалуйста, ребята? Я отображаю это emails
состояние, но когда я удаляю электронное письмо из массива в handleDelete
map
, оно не отображается повторно. Когда я console.log(emails)
все правильно, электронное письмо удаляется правильно.
import { TextField, Chip, Avatar } from "@material-ui/core";
import React, { useState } from "react";
import "./Email.css";
export default function Email() {
const [value, setValue] = useState<string>();
const [emails, setEmails] = useState<string[]>([]);
function onTextChange(e: any) {
setValue(e.target.value.replace(" ", ""));
if (value?.includes(",")) {
let separated = e.target.value.split(",");
const re = /^(([^<>()[]\.,;:s@"] (.[^<>()[]\.,;:s@"] )*)|(". "))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9] .) [a-zA-Z]{2,}))$/;
const newEmails = separated.filter((val: any) => re.test(val));
if (newEmails[0] !== undefined) {
emails.push(newEmails[0]);
setEmails(emails);
console.log(emails);
}
setValue("");
}
}
function handleDelete(email: string) {
const index = emails.indexOf(email);
if (index > -1) {
setEmails(emails.splice(index, 1));
console.log(email, "removed");
console.log('new list', emails)
}
}
return (
<div>
<TextField
value={value || ""}
variant='outlined'
onChange={onTextChange}
id='textInput'
InputProps={{
startAdornment: (
<div style={{ top: "50%" }}>
{emails.map((email: any) => (
<Chip
label={email}
key={email}
avatar={<Avatar>{email[0].toUpperCase()}</Avatar>}
onDelete={() => handleDelete(email)}
style={{ display: "-webkit-inline-box" }}
/>
))}
</div>
),
}}
/>
</div>
);
}
Ответ №1:
Проблема в том, что это setEmails(emails.splice(index, 1));
соединение строк просто изменяет массив на месте, поэтому расположение памяти для массива не меняется, поэтому react не видит изменений.
Вы хотите что-то вроде этого setEmail(prevEmails => prevEmails.filter(e => e !== email))
Комментарии:
1. Большое вам спасибо! Решена проблема, и это намного понятнее, чем мое решение!
Ответ №2:
Да, я уже сталкивался с подобной проблемой раньше. Во-первых, это потому, что переменная «электронные письма» не изменяется. Итак, я имею в виду, что вы вызываете функцию email.splice, но переменная email не изменилась. Вы должны создать новую переменную массива и установить в нее измененное значение. Только тот слушатель, который реагирует на изменение состояния, может понять, что значение «электронные письма» изменилось, поэтому «я должен снова отобразить функцию ..».
function handleDelete(email: string) {
const newEmails = [...emails];
const index = newEmails.indexOf(email);
if (index > -1) {
setEmails(newEmails.splice(index, 1));
}
}
Комментарии:
1. Имеет смысл, но все равно не изменился таким образом