Состояние React useState не меняется

Я новичок в React.

У меня есть список вкладок в App.js:

const [tabs, setTabs] = useState([
{id:0, name:"TOS", content:(<WelcomeTab title='title' isChecked = {isTosChecked} setIsChecked = {setIsTosChecked}/>), unviewed:0, visible:false}, 
......
])

Также у меня есть компонент флажка, который работает отлично. <WelcomeTab/> есть один внутри. Мне нужно получить доступ к состоянию этого флажка из App.js, поэтому у меня есть const [isTosChecked, setIsTosChecked] = useState(false) в App.js.

Но когда я пытаюсь нажать флажок, состояние не меняется.

Я попытался поставить <WelcomeTab/> прямо в рендер App.js, и все работает отлично. Но когда он находится в списке вкладок и отображается вот так

{tabs.map(tab => 
  <div key = {tab.id} className = {tab === activeTab ? "tab selected" : "tab"}>
    {tab.content}
  </div>
)}

нажатие флажка не меняет состояние.

После отладки я понял, что не могу изменить (ничего не происходит, переменная isChecked не меняется) состояние WelcomeTab или Checkbox в случае использования списка вкладок.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

См. связанные коды и окно с консолью.logs, объясняющее, что происходит.

Вы передаете JSX в исходное состояние, которое оценивается ровно один раз во время первоначального рендеринга. Вы щелкаете и меняете isTosChecked, что обновляет переменную и вызывает повторную визуализацию родительского элемента, что также влияет на дочерние элементы. Но состояние вкладок не изменилось - начальное значение больше не оценивается (то есть все, что входит в useState в качестве начального аргумента). Поскольку вкладки не изменились (также учтите, что изменения в непримитивных состояниях оцениваются по ссылке), данные, отображаемые jsx, устарели.

В целом я бы не рекомендовал делать то, что вы сделали. Очень странно вкладывать JSX внутрь состояния (где jsx также содержит другое состояние). Мои коды и ящик НЕ отражают лучшие практики.

Вы можете использовать const tabs = [...] без состояния, поскольку состояние используется, когда вы хотите запустить повторный рендеринг с данными, которые могут быть изменены, но jsx - это просто статические данные (принимающие состояние в свои реквизиты, все равно вызывающие повторный рендеринг). Он должен получить все, что ему нужно для выполнения своей работы, через реквизиты, которые могут быть состояниями.

Другие вопросы по теме