Как принудительно отобразить компонент в React

#reactjs #rxjs #reactive-programming #flux

#reactjs #rxjs #реактивное программирование #поток

Вопрос:

Я выполняю простой ajax-вызов API, который выдает данные каждые 5 секунд, данные получены правильно с использованием наблюдаемых, и состояние данных обновляется, как и ожидалось. проблема в том, что страница отображается только один раз при загрузке, а не при изменении даты с помощью функции setData . если я перезагружу страницу, перейдя по другой ссылке, а затем вернусь, данные будут отображаться, как и ожидалось, это код:

 function MyComponent() {

   const [data, setData] = useState(RxJSStore.getData())

   useEffect(() => {
       RxJSStore.addChangeListener(onChange);
       if (data.length === 0) loadDataRxJSAction()
       return () => RxJSStore.removeChangeListener(onChange)
   }, [data.length])


   function onChange() {
       setData(RxJSStore.getData())
   }

   return (
       <>
            <List data={data} />

       </>
   )
}
 

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

1. вы уверены, что длина данных изменяется? Кроме того, я не думаю, что хорошей практикой является запуск асинхронного вызова со значением по умолчанию для useState

2. спасибо, Дарио, да, длина массива данных меняется каждый раз, когда я получаю новый ответ от моего вызова ajax (состояние обновляется в хранилище, затем оно принимается в компоненте, поскольку у меня есть onChange (), который обновит массив данных), поэтому массив данных обновляется правильно

3. Не могли бы вы предоставить изолированную среду для кода?

4. codesandbox.io/s/strange-wescoff-sxbwx?file=/src/…

5. Спасибо, я выпишу ему чек завтра утром, мне нужно будет идти.

Ответ №1:

Есть способ обойти это, заставляя компонент отображать каждый раз, когда вызывается метод onChange. В документации написано, что это должно использоваться только для целей тестирования, но поскольку в ситуации нет другого решения, это может быть решением для данного варианта использования.

 import { useRefresh } from 'react-tidy'

 function MyComponent() {

 const [data, setData] = useState(RxJSStore.getData())
const refresh = useRefresh()

useEffect(() => {
   RxJSStore.addChangeListener(onChange);
   if (data.length === 0) loadDataRxJSAction()
   return () => RxJSStore.removeChangeListener(onChange)
}, [data.length])


  function onChange() {
    setWarnings(RxJSStore.getWarnings())
    refresh()
}

return (
   <>
        <List data={data} />

   </>
 )
}