#reactjs #react-hooks #use-state
Вопрос:
таким образом, у меня есть код, который предназначен для изменения порядка списка пользователей, напечатанных на таблице по имени. Когда я просто консолирую.log() упорядоченный массив, он отлично работает. Как только я представлю useState, он обновится только один раз.
итак, вот оригинальный рабочий код
import React from 'react' import { useState } from 'react' export const Table = () =gt; { // ///////////////////UseState Array // let asc = true var newArr const [Array2,SetArray] = useState([ {rank:1,name:'Sam', age:25, gender:true}, {rank:2,name:'Bill', age:35, gender:true}, {rank:3,name:'John', age:22, gender:true}, {rank:4,name:'Sarah', age:19, gender:false}] ) const Alpha2 = ()=gt;{ console.log(asc) if (asc===true){ newArr = [...Array2].sort((a,b) =gt; (a.namegt; b.name) ? 1 : ((b.name gt; a.name) ? -1 : 0)) asc = false console.log('cond 1') } else if(asc=== false ){ newArr = [...Array2].sort((a,b) =gt; (b.namegt; a.name) ? 1 : ((a.name gt; b.name) ? -1 : 0)) asc = true console.log('cond 2') } console.log(newArr) } // return ( lt;div className="Table"gt; lt;/divgt; lt;h3gt;Table 2lt;/h3gt; lt;div className="Standings"gt; lt;div className="column"gt; lt;divgt; lt;h3gt;Ranklt;/h3gt;lt;/divgt; lt;div onClick= {()=gt;Alpha2()}gt; lt;h3 gt;Namelt;/h3gt;lt;/divgt; lt;divgt; lt;h3 onClick= {()=gt;Numa()}gt;Agelt;/h3gt;lt;/divgt; lt;divgt; lt;h3gt;Genderlt;/h3gt;lt;/divgt; lt;/divgt; {Array2.map((profile)=gt;( lt;div key={profile.rank} className="column"gt; lt;divgt; lt;h3gt;{profile.rank}lt;/h3gt;lt;/divgt; lt;divgt; lt;h3gt;{profile.name}lt;/h3gt;lt;/divgt; lt;divgt; lt;h3gt;{profile.age}lt;/h3gt;lt;/divgt; lt;divgt; lt;h3gt;{profile.gender?'male': 'female'}lt;/h3gt;lt;/divgt; lt;/divgt; ))} lt;/divgt; lt;/divgt; ) } export default Table
он консольно регистрирует упорядоченный массив после нечетного числа щелчков, как
: {rank: 2, name: 'Bill', age: 35, gender: true} 1: {rank: 3, name: 'John', age: 22, gender: true} 2: {rank: 1, name: 'Sam', age: 25, gender: true} 3: {rank: 4, name: 'Sarah', age: 19, gender: false}
и после четного числа щелчков, как
0: {rank: 4, name: 'Sarah', age: 19, gender: false} 1: {rank: 1, name: 'Sam', age: 25, gender: true} 2: {rank: 3, name: 'John', age: 22, gender: true} 3: {rank: 2, name: 'Bill', age: 35, gender: true}
Именно этого я и хочу, так как каждый раз он переставляется в алфавитном порядке (один раз по убыванию, а другой раз по возрастанию). Переменная asc продолжает вращаться между true и false.
но когда я использую функцию useState setArray, изменяя функцию Alpha2 следующим образом
const Alpha2 = ()=gt;{ console.log(asc) if (asc===true){ newArr = [...Array2].sort((a,b) =gt; (a.namegt; b.name) ? 1 : ((b.name gt; a.name) ? -1 : 0)) asc = false console.log('cond 1') } else if(asc=== false ){ newArr = [...Array2].sort((a,b) =gt; (b.namegt; a.name) ? 1 : ((a.name gt; b.name) ? -1 : 0)) asc = true console.log('cond 2') } SetArray(newArr) console.log(newArr) }
Он изменяет массив только один раз в
rank: 2, name: 'Bill', age: 35, gender: true} 1: {rank: 3, name: 'John', age: 22, gender: true} 2: {rank: 1, name: 'Sam', age: 25, gender: true} 3: {rank: 4, name: 'Sarah', age: 19, gender: false}
но впоследствии это остается неизменным, так как переменная asc никогда не меняется с false обратно на true, как это было бы в более ранней версии функции
так что же происходит? Что я делаю не так?
Комментарии:
1. Несвязанное, но последовательное, разумное форматирование кода значительно облегчает обдумывание кода. Это похоже на ~90 строк, из которых 1/3 пустые, а поток/логика скрыты случайным отступом.
2. Извините за это, мне пришлось удалить другие функции, которые не входили в вопрос, поэтому я не редактировал должным образом после удаления и оставил много пробелов пустыми.
3. В любом случае,
asc
это не переменная, которая вызовет повторную визуализацию, потому что это не ссылка на состояние или свойство. Я не совсем могу прочитать код, но, скорее всего, вы хотите повлиять наasc
то, какие обновленияArray2
. (Также не связано, но я бы придерживался обычных соглашений об именах JS, чтобы все было более понятно.)
Ответ №1:
Причина, по которой это происходит, заключается в том, что useState повторно отображает страницу, а простое изменение переменной ‘asc’ с true на false-нет.
По сути, всякий раз, когда вы вызываете useState, он обновляет страницу и при этом сбрасывает любую жестко закодированную переменную обратно к ее исходному значению.
Единственный способ изменить это-использовать хук для переменной ‘asc’, как это
const [asc, setAsc] = useState(true)
а затем измените его с помощью
setAsc(false)
Это должно все исправить.