React本机组件不会对mobx可观察的数据更改做出反应

时间:2018-02-17 18:44:11

标签: react-native mobx mobx-react

所以我开始使用react native和mobx构建一个新的应用程序。 我有一个平面列表组件,从mobx商店列表中获取他的状态数据。当我将新项目添加到mobx列表时,它不会再渲染平面列表视图。

这是我的代码:

列表组件:

@inject('TravelStore')
@observer
class TripsList extends Component {

constructor(props) {
    super(props);
    this.state = {
        trips_list: props.TravelStore.trips_list
    }
};

// set the navigation bar options
static navigationOptions = ({ navigation }) => {
    const { params = {} } = navigation.state;
    return {
        title: 'Your Trips',
        headerRight: (
            <Button transparent primary onPress={ params.addNewTrip }>
                <Icon name='ios-add' />
            </Button>
        )
    };
};

// connect between component functions to header
componentDidMount() {
    this.props.navigation.setParams({ 
        addNewTrip: this._addNewTrip.bind(this),
    });
}

_addNewTrip() {
    this.props.TravelStore.addNewTrip('bla')
}

_renderListItem({ item }) {
    return (
        <TripsListItem details={item} navigation={this.props.navigation}/>
    );
};

render() {
    return (
        <Container>
            <FlatList
                data = {this.state.trips_list}
                renderItem = {this._renderListItem.bind(this)}
                keyExtractor={(item, index) => index}
            />
        </Container>
    );
};
}

mobx商店:

class ObservableTravelListStore {

@observable trips_list = [
    {
        name: 'to denver',
        trip_cost: 400,
        buying_list: [
            { name: 'pizza', price: 10 },
            { name: 'burger', price: 40 },
            { name: 'ipad', price: 44 },
            { name: 'bus', price: 45 },
        ]
    },
    {
        name: 'to yafo',
        trip_cost: 30,
        buying_list: [
            { name: 'na na na', price: 10 },
            { name: 'burger', price: 40 },
        ]
    },
    {
        name: 'to tel aviv',
        trip_cost: 50,
        buying_list: [
            { name: 'na na na', price: 10 },
            { name: 'no no no', price: 40 },
        ]
    },
]


@action addNewTrip (trip_data) {
    this.trips_list.push({
        name: 'newTrip',
        trip_cost: 6060,
        buying_list: [
            { name: 'na na na', price: 10 },
            { name: 'burger', price: 40 },
        ]
    })

    console.log(this.trips_list[3])
}

}

const TravelStore = new ObservableTravelListStore()
export default TravelStore

任何想法为什么TripsList组件在调用addNewTrip函数时不会重新渲染?

2 个答案:

答案 0 :(得分:0)

问题是你没有听到真实的可观察对象,而是对它的副本,你在构造函数中保存状态。

<FlatList
     data = {this.state.trips_list}//change this
     renderItem = {this._renderListItem.bind(this)}
     keyExtractor={(item, index) => index}
            />

<FlatList
     data = {this.props.TravelStore.trips_list}//change to this
     renderItem = {this._renderListItem.bind(this)}
     keyExtractor={(item, index) => index}
            />

渲染函数就像mobx的autobind,如果它是观察者的渲染函数,它会对observable中的变化作出反应

如果您想对列表项中的内部更改做出反应, 你应该添加一个可观察的方案,这应该做的, 像这样的东西:

class TripModel {
    @observable name = ''
    @observable trip_cost = 0
    @observable buying_list = []

constructor(name, cost, buy_list){
    this.name = name
    this.trip_cost = cost
    this.buying_list = buy_list
}
/* class functions*/
}
class ObservableTravelListStore {

@observable trips_list = [
     new Trip(
            'to denver',
             400,  
             [
               { name: 'pizza', price: 10 },
               { name: 'burger', price: 40 },
               { name: 'ipad', price: 44 },
               { name: 'bus', price: 45 },
              ]
             ),
     new Trip(
            'to yafo',
             30,  
             [
                { name: 'na na na', price: 10 },
                { name: 'burger', price: 40 },
             ]
             ),
     new Trip(
            'to tel aviv',
             50,  
             [
            { name: 'na na na', price: 10 },
            { name: 'burger', price: 40 },
             ]
             )
  ]


@action addNewTrip (trip_data) {
    this.trips_list.push(new Trip(
            'newTrip',
             6060,  
             [
            { name: 'na na na', price: 10 },
            { name: 'burger', price: 40 },
             ]
             ))

}

}

const TravelStore = new ObservableTravelListStore()
export default TravelStore

这只是更好地规划反应式应用,因此在更改列表中项目的内部内容时,您将对此更改作出反应

希望有所帮助

答案 1 :(得分:0)

这是一篇旧文章,但最近我也陷入了类似的困境。在Flatlist属性列表中添加extraData对我有所帮助。

<FlatList
    data = {this.props.TravelStore.trips_list}
    renderItem = {this._renderListItem.bind(this)}
    keyExtractor={(item, index) => index}
    extraData={this.props.TravelStore.trips_list.length} // list re-renders whenever the array length changes
/>

正如@Omri指出的那样,您不应该在Component状态下存储可观察对象,而应直接对其进行更改。