Итак, я собираю номера мобильных телефонов из textarea
: значения сохраняются в состоянии.
Я проверю их и/или добавлю префикс страны в зависимости от того, есть ли у них префикс. Для каждого проверенного числа я хочу сохранить его в массиве.
После того, как я отправлю данные в массив с помощью вызова fetch
, я хочу, чтобы содержимое массива было сброшено в пустой массив, чтобы подготовить его к приему новой партии чисел.
Я разложил проблему на две функции. Один для обработки номеров, а другой для звонка fetch
.
.
.
.
const [phoneNos, setPhoneNos] = useState('') // values from the textbox
const [validatedPhoneNos, setValidatedPhoneNos] = useState([]); // array to hold validated numbers
function addPhoneNosToDB () {
fetch(`end_point`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
mode: 'cors',
body: JSON.stringify({
somefield: fieldValue,
list: validatedPhoneNos
}),
}).then(r => {
toast.success('Your list was added')
setPhoneNos('');
setValidatedPhoneNos([]) // ***
}).catch(err => toast.warning(err))
}
//function to validate and format numbers
function procPhoneNos () {
if (phoneNos) {
const countryCodePattern = /^(?:\+?234|0)?(7\d{8})$/;
const phoneNumberPattern = /^(0|\+?234)(\d{10})$/;
let list = phoneNos.split(',').map(phoneno => phoneno.trim());
list.forEach(phoneNumber => {
if (phoneNumber.match(countryCodePattern)) {
setValidatedPhoneNos(prev => [...prev, phoneNumber])
} else if (phoneNumber.match(phoneNumberPattern)) {
setValidatedPhoneNos(prev => [...prev, phoneNumber.replace(phoneNumberPattern, '234$2')]);
} else {
toast.warning("One or more phone numbers not properly formatted")
return
}
});
//call the function to submit formatted numbers to db
addPhoneNosToDB()
} else toast.warning("you need to enter at least one phone number")
}
Проверяя это, я получаю пустой массив при каждом вызове addPhoneNosToDB
. Если я удалил строку ***
, я получу числа в массиве, но в основном только после второго запроса. Кроме того, все предыдущие номера телефонов сохраняются в массиве. Как это исправить, чтобы элементы массива очищались только после успешного запроса fetch
? Предпочтительно без useEffect, за исключением случаев необходимости.
Спасибо
Помогает ли метод установки useState не сразу отражать изменение ответить на ваш вопрос?
Я вызываю функцию addPhoneNosToDB
, которая затем использует содержимое массива в состоянии для вызова fetch
.
Состояние validatedPhoneNos
избыточно. Вы используете его только для передачи массива телефонных номеров между функциями. Поскольку procPhoneNos
вызывает addPhoneNosToDB
, просто передайте массив list
от одного к другому.
Примечание. Я внес в ваш код и другие несвязанные изменения. Смотрите комментарии.
const [phoneNos, setPhoneNos] = useState('') // values from the textbox
function addPhoneNosToDB(list) { // pass the list to the function
fetch(`end_point`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
mode: 'cors',
body: JSON.stringify({
somefield: fieldValue,
list // send the list
}),
}).then(r => {
toast.success('Your list was added')
setPhoneNos('');
}).catch(err => toast.warning(err))
}
// function to validate and format numbers
function procPhoneNos() {
if (!phoneNos) { // if not phone numbers show toast and
toast.warning("you need to enter at least one phone number");
return;
}
const countryCodePattern = /^(?:\+?234|0)?(7\d{8})$/;
const phoneNumberPattern = /^(0|\+?234)(\d{10})$/;
let invalid = false; // a flag to check if there are invalid numbers
const list = phoneNos.split(',')
.map(phoneno => { // the map can be used to check and transform the numbers
const phoneNumber = phoneno.trim();
if (phoneNumber.match(countryCodePattern)) return phoneNumber;
if (phoneNumber.match(phoneNumberPattern)) return phoneNumber.replace(phoneNumberPattern, '234$2');
invalid = true; // set to true when invalid number is encountered
return phoneNumber;
});
// show warning if the flag is true
if (invalid) toast.warning("One or more phone numbers not properly formatted")
//call the function to submit formatted numbers
addPhoneNosToDB(list) // pass list to function
}
Где и как вы проверяете/подтверждаете, что состояние
validatedPhoneNos
не обновляется до пустого массива? Вы просто пытаетесь сохранить журналvalidatedPhoneNos
в консоли сразу после поставленного в очередь обновления? Пожалуйста, отредактируйте, чтобы более подробно уточнить, в чем проблема, и предоставить любые сведения об отладке.