Хук useState вызывается внутри функции карты, вызывая бесконечный цикл - PullRequest
1 голос
/ 05 февраля 2020

В настоящее время я создаю динамический движок форм c и хочу отобразить результаты из хранилища избыточных данных при визуализации компонента Сводка ответа. Я подумал, что лучше всего сделать это, если у вас будет статус «завершено» и он будет установлен в «истина» после загрузки компонента answerSummary, но выполнение этого в функции карты не работает и вызывает бесконечную реакцию l oop. ошибка.

Код здесь:

function App() {
  let [complete, setComplete] = useState(false);
  return (
    <div>
      <h1>Form App Prototype</h1>
      <Router>
        <Switch>
          {Object.values(Database.steps).map(step => {
            step.name === 'answerSummary' ? setComplete(true) : setComplete(false);
            return (

              <Route exact path={`/${step.name}`} render={() =>
                <Step step={step} />

              }
              />
            )
          })}
        </Switch>
      </Router>
        <br></br>
        <div style={{display: complete? 'block' : 'none'}}><StoreVisual/></div>

    </div>
  );
}

export default App;

РЕДАКТИРОВАТЬ: я знаю, что вы не можете установить setState внутри рендера - я написал это таким образом, чтобы попытаться передать что я хочу уметь

Ответы [ 4 ]

1 голос
/ 05 февраля 2020

Мое понимание вашей проблемы заключается в том, что вы пытаетесь отобразить результаты после монтирования компонента итогового ответа. Вы можете добиться этого, используя хук useEffect, который запускается при монтировании компонента. https://reactjs.org/docs/hooks-effect.html

0 голосов
/ 05 февраля 2020

Если вы хотите визуализировать <StoreVisual/> только когда они находятся на последнем шаге, может быть проще установить хук состояния для индекса шага, на котором находятся люди.

 const [index, setIndex] = useState(0);

Каждый раз кто-то шаг за шагом увеличивает это значение.

Для этого вам нужно будет передать setIndex, или как вы его называете, в компонент Step.

Затем вы можете отрендерить <StoreVisual/> с условным, вот так ...

<div>
      <h1>Claimer Form App Prototype</h1>
      <Router>
        <Switch>
          {Object.values(Database.steps).map(step => 
              <Route exact 
                     path={`/${step.name}`} 
                     render={() => <Step step={step} /> }/> )}
        </Switch>
      </Router>
        <br></br>
        {Database.steps[index] === 'answerSummary' && <StoreVisual/>}
    </div>

Этот подход также дает вам простой способ позволить людям начать с середины формы. Скажем, вы хотите, чтобы в будущем люди могли сохранять недоделанные формы, просто измените / обновите значение индекса по умолчанию.

0 голосов
/ 05 февраля 2020

Вместо того, чтобы запускать этот код при возврате, создайте массив в своей функции logi c:

function App() {
  let [complete, setComplete] = useState(false);
  // build an array of Route components before rendering
  // you should also add a unique key prop to each Route element
  const routes = Object.values(Database.steps).map(step => {
    step.name === 'answerSummary' ? setComplete(true) : setComplete(false);
    return <Route exact path={`/${step.name}`} render={() => <Step step={step} />} />
  })
  return (
    <div>
      <h1>Claimer Form App Prototype</h1>
      <Router>
        <Switch>
          // render the array 
          {[routes]}
        </Switch>
      </Router>
      <br></br>
      <div style={{display: complete? 'block' : 'none'}}><StoreVisual/></div>
    </div>
  );
}

export default App;

Я не думаю, что вам нужно вызывать setComplete(false) на основе этой логики c, поэтому вам, вероятно, следует заменить свою троицу на выражение if:

if (step.name === 'answerSummary') {
  setComplete(true)
}

и избегать ненужных вызовов функций

0 голосов
/ 05 февраля 2020

Вы не можете установить состояние внутри рендера, которое вызывает бесконечность l oop. [При каждом изменении состояния компонент будет перерисовываться (вызывает функцию рендеринга)]

render () => setState () => render () => setState () ....... бесконечно

WorkAround:

<div style={{display: this.props.location.pathname=='answerSummary'? 'block' : 'none'}}><StoreVisual/></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...