#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} />
</>
)
}