Слетают выбранные чекбоксы и инпуты при перерисовке компонента
У меня есть состояние questions, массив, что я получаю от сервера, при первом подключении, устанавливаю состояние setQuestions равное вопросам (билетам) от сервера. Затем я отображаю их с помощью questions.map. У меня используются UI компоненты в этих билетах что рендерю, и при получении новых билетов, те, что чекнул пользователь (radio/input/checkbox) слетают. Решил использовать React.memo, чтобы отображать те билеты, которых нет в quesitons, помогло, при получении новых билетов действия перестали слетать, однако теперь не знаю, как вызвать перерисовку теперь тех билетов, у которых изменилось свойство checked на true. Т.е какой-то пользователь проголосовал в билете, билет попал на сервер, и разослал всем клиентам, что данный вопрос уже решен. Но как вызвать перерисовку этого билета ?
Теперь говоря проще, мне нужно обновлять билеты, но так, чтобы значения выбранных пользователем чекбоксов и инпутов при перерисовки билетов не слетало. В идеале конечно чтобы перерисовывались только те билеты, что новые и у которых checked = true. Но буду благодарен, если покажите даже простое решение с перерисовкой всех билетов, и сохранением выбранного пользователем действия. Я больше по нативному JS, потому в React не такой подкованный.
//предотвращение перерисовки всех компонентов
const QuestionItem = React.memo(({ question }) => {
return (
<Question
type={question.type}
questionId={question.id}
images={question.images}
qNum={question.number}
vNum={0}
title={question.title}
selects={question.selects}
/>
);
});
... код
//комната
const Room = () => {
//вопросы (билеты)
const [questions, setQuestions] = useState([]);
... код
//обработчик новых вопросов
const incQuestionHandler = (request) => {
setQuestions((prevItems) => [...prevItems, request.data]);
}
//первичная загрузка билетов
useEffect(() => {
//получение билетов
emitGetQuest(getRoomQuests);
//прослушивание билетов
socket.on('update-question-data', incQuestionHandler);
//убрать прослушку
return () => {
socket.off('update-question-data', incQuestionHandler);
}
}, [])
return (... код
<div className='center-content'>
<VoteInfo/>
{questions.map((question, n) => ( <--------- отрисовка билетов
<QuestionItem key={question.id} question={question}/>
))}
</div>
)
Я также пробовал просто перерисовывать все билеты, не прибегая к React.memo, тестировал на небольшим компоненте, где все работало, и чекбоксы и инпуты не слетали, однако это не работает для компонента Questions, в нем в свою очередь также идет отрисовка вариантов ответов с помощью map, вот код:
//билеты
const Question = (props) => {
//установить варианты ответов для вопроса
const QuestionSelection = (props) => {
const {parentProps} = props;
//билет
let element;
//проверка на тип билета
switch(parentProps.type){
case 'radio':
element = <Radio selects={parentProps.selects} questionId={parentProps.questionId}/>
break
case 'checkbox':
element = <Check selects={parentProps.selects} questionId={parentProps.questionId}/>
break
case 'dropout':
element = <Dropout selects={parentProps.selects} questionId={parentProps.questionId}/>
break
case 'input':
element = <TextInput maxLength='250' questionId={parentProps.questionId}/>
break
default:
element = null
break
}
return element;
}
...код
return (
...код
//ТУТ ОТРИСОВЫВАЕТСЯ ТИП БИЛЕТА В QuestionSelection
<div className='middle-quest-content'>
<div className='quest-title-content'>
<img className='test-info-icon' src={questIcon}></img>
<span className='simple-span test-info-text'><ParseTextAndInsertImages images={props.images} title={props.title}/></span>
</div>
<QuestionSelection parentProps={props}/>
</div>
...код
)
}
export default Question;
Ответы (1 шт):
Проблема решена, я немного не вник, и мне следовало передавать checked в пропс мемонизированного компонента, чтобы вызвать его перерисовку.
return (... код
<div className='center-content'>
<VoteInfo/>
{questions.map((question, n) => ( <--------- отрисовка билетов
<QuestionItem checked={question.checked} key={question.id} question={question}/>
))}
</div>