Цитата:
В консоли все нормально, но тут же ошибка про попытку менять отслеживаемые данные... Скоро поеду на работу - сделаем примеры, покажу тут. |
Ситуация получается более запутанной...
Сделал я тестик простенький и у меня все заработало без всяких предупреждений! Хранилище import {makeAutoObservable} from 'mobx' class Test { data = { arr: [ {id: '0', name: 'Item 0'}, {id: '1', name: 'Item 1'}, {id: '2', name: 'Item 2'}, ] } constructor(props) { makeAutoObservable(this) } add(obj) { this.data.arr.push(obj) } } export default new Test() Собственно экран import React from "react" import { StyleSheet, Text, View, Button, FlatList } from 'react-native' import { observer} from 'mobx-react-lite' import { toJS } from "mobx" import test from '../store/test' function Test() { //console.log(1, test.data.arr) const arr = toJS(test.data.arr) //console.log(2, test.data.arr) const renderItem = ({ item }) => ( <Text>{item.name}</Text> ) return ( <View style={styles.container}> <View style={styles.container}> <Button title='Add' onPress={add} /> </View> <FlatList data={test.data.arr} renderItem={renderItem} keyExtractor={item => item.id} /> </View> ) function add() { const l = test.data.arr.length test.add({ id: l.toString(), name: 'Item ' + l }) } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, tab: { margin: 50 } }) export default observer(Test) Все рисуется и так нормально... НО! :) если убрать const arr = toJS(test.data.arr) Перестает работать добавление элементов. :blink: Возвращаю эту строку - работает добавление. А по предыдущей проблеме - сказал чтобы ребята начали искать у себя проблемы глубже... |
Цитата:
Было асинхронное чтение данных с сервера. Изменение состояния обернули в runInAction() из mobx и ошибка ушла. FlatList стал отображать данные из хранилища mobx без замечаний. Но по моему примеру все еще интересно что так влияет на работоспособность кнопки Add в моем примере? :-? |
Цитата:
без toJS ты читаешь только test.data.arr (и как следствие подписываешься только на изменение test.data.arr), а он не меняется, массив тот же самый, только в него запушили. вызов toJS(test.data.arr) делает чтение вообще всего, что есть внутри массива, и соответственно подписки будут на все изменения. и конечно, здесь не самая экономичная схема перерендеров. Что-то поменяли, и перерендеривается всё. Тут надо тоже смотреть по ситуации, как лучше сделать, и разумеется, без toJS |
Цитата:
|
Цитата:
Цитата:
Цитата:
В "простом" Реакте вполне хватало использования "сторных" методов и все перерисовывалось... А теперь этого мало... :( |
А потому, что он цепляется через жёпу. Потому что реакт - не расширяем нихрена. Вызовы рендера: стейт - отдельно, пропс - отдельно, нужен стор? - тоже отдельно.
Можешь попробовать энтот твой FlatList в <Observer><FlatList ...></Observer> заключить, но это так - выстрел в небо, загружать сейчас в голову весь контекст как оно там на самом деле работает откровенно лень.) |
Цитата:
Цитата:
я бы попробовал так: const MobxFlatList = observer(FlatList) и потом юзать MobxFlatList. А уж если такое не поможет - менять массив иммутабельно, то есть вместо test.data.arr.push(newItem) делать test.data.arr = [...test.data.arr, newItem] ну и там далее ещё кое-где поменять. использовать в рендере toJS - это антиMobX |
Цитата:
Не помогает. Цитата:
Цитата:
Цитата:
|
Цитата:
import React from "react" import { StyleSheet, Text, View, Button, FlatList } from 'react-native' import { observer} from 'mobx-react-lite' import { toJS, runInAction } from "mobx" import test from '../store/test' function Test() { //const arr = toJS(test.data.arr) const renderItem = ({ item }) => ( <Text>{item.name}</Text> ) const MobxFlatList = observer(FlatList) return ( <View style={styles.container}> <View style={styles.tab}> <Button title='Add' onPress={add} /> </View> <MobxFlatList data={test.data.arr} renderItem={renderItem} keyExtractor={item => item.id} /> </View> ) function add() { const l = test.data.arr.length test.add({ id: l.toString(), name: 'Item ' + l }) } } const styles = StyleSheet.create({ container: { flex: 1, color: '#000', backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, tab: { margin: 70 } }) export default observer(Test) Ошибка Cannot call a class as a function |
Часовой пояс GMT +3, время: 12:58. |