Javascript (React) динамически не отображает коллекцию

javascript #reactjs

#javascript #reactjs

Вопрос:

Я пытаюсь создать базовую многоступенчатую веб-форму на Javascript. Я хотел выполнить что-то вроде раздела «Формы» в Full Stack Open, создав коллекцию (массив) вопросов, затем отобразив их в виде меток на моей веб-странице, отфильтрованных так, чтобы в определенное время появлялись только подходящие. Например, когда вы впервые посещаете страницу, на ней будет написано «Следующие несколько вопросов позволят оценить ситуацию с вашим бюджетом», затем, после нажатия кнопки «Пуск», она перейдет к первому вопросу, затем к следующему, ко второму и так далее.

Я думал, что выполнил это правильно, отобразив отфильтрованную коллекцию (фаза инициализируется значением 0 вне приложения):

  const questionPhase = () => {
      
        if (phase < 3){
            phase = phase   1;
      
        }
            
        else if(phase == 3){
            phase = 0;
            addToBudget(attribute);              
        }
        console.log(phase);
         
}
 return (
    <div>
        <h3> Please answer some questions to start</h3>
        <ul>
            {questions.filter(question => question.phase === phase).map(question =>
                { < label > {question.script} 
                <input type="text"
                question = {question.attribute}
                value={question.attribute}
                onChange={handleInput}
                />
                </label>})}
        </ul>
        <button onClick={questionPhase}> {phase === 2 ? 'Next' : 'Submit'} </button>
    </div>
)
 

Я провел некоторое протоколирование и определил, что фаза фактически меняется каждый раз, когда я нажимаю кнопку внизу. Но чего не происходит, так это либо отображения вопросов (и меток), либо изменения надписей на кнопках.

Я не уверен, что я сделал не так? Я уверен, что есть какой-то тонкий аспект потока управления, который я пропустил, но я не знаю, что — я понял, что, как объясняется в FSO, приложение постоянно запускается каждый раз, когда происходит изменение путем нажатия кнопки или чего-то еще, что должно быть событием, созданным кнопкойнажмите.

Заранее благодарю вас за любую помощь

приложение: вот класс questionsList (из которого импортируются вопросы) и обработчик событий:

 
        import React from 'react'
    
    const questions = [
    
        {
            phase: 1 ,
            script: 'What is your monthly income?',
            attribute: "income"
        },
        
        {
            phase: 2,
            script: 'what are you monthly expenses?',
            attribute: "expenses"
        }
    ]
    
    export default questions

 
 const handleInput = (event) => {
    const value = event.target.value;
    console.log('valued!')
    setAttribute({
        ...attribute,
        [event.target.question]: value
    })

}
 

Комментарии:

1. Хотя я не могу полностью ответить на ваш вопрос, у меня есть небольшой совет для вашего вклада. Вместо этого question = {question.attribute} вы можете передать дополнительные данные (помимо того, что есть в событии) через onChange prop. Вот так onChange={(e) => handleInput(e, question.attribute)} .

2. Является ли код всем, что вы пишете для проекта? Вы пробовали использовать React hook?

3. @Julien спасибо тебе! Я полагаю, это делает код более чистым

4. @jacobkim не могли бы вы объяснить, что вы имеете в виду, я немного больше? Я не совсем понимаю, к чему вы клоните

5. @Брэндон, я хотел бы знать, использовали ли вы state или hook для React. Изменение чисел обработчиками событий для javascript не работает для React. Потому что возвращаемые теги в компонентах на самом деле не являются тегами, а являются так называемым JSX.

Ответ №1:

Единственное, что вызовет повторный рендеринг в React, — это изменение состояния, поэтому, если изменение переменной должно вызвать повторный рендеринг, вы должны вставить его в состояние.

Вы можете изменить свой компонент questionPhase на класс или функцию (то же самое), а затем в конструкторе определить

this.state = {фаза};

Тогда this.state.phase будет равен любой фазе, которая была при создании экземпляра компонента. Вы захотите изменить остальную часть компонента, чтобы использовать эту переменную. Правильный способ изменить его значение и запустить повторный рендеринг — это вызвать setState .

Именно так я бы это и сделал; хотя было бы проще просто вызвать forceUpdate . Это приведет к повторному рендерингу react. Однако это не способ реагирования. Вся цель react — сильно привязать пользовательский интерфейс к базовому состоянию, поэтому я бы не рекомендовал использовать forceUpdate .

Комментарии:

1. Это то, что я тоже собирался добавить, Брэндон. Ваш phase хранится в состоянии?

2. @Julien — значит, что-то вроде (phase, setPhase) = useState(0) будет работать? Спасибо, что рассказали о forceUpdate, это звучит немного странно, а не то, как я чему-то научился (мой новичок, по крайней мере, lol). Я ценю помощь, теперь это имеет гораздо больше смысла.