mobX - Filter countries in react native?

吃可爱长大的小学妹 提交于 2019-12-07 16:55:50

问题


I have an array of 3 countries and a text input to filter them. If you type in the text input, it should check for what you typed against the country name, which should return the new filtered list of countries that match the filtered text. It should also display the inputted text next to Typed Text:

import React, { Component } from 'react'
import { View, Text, TextInput } from 'react-native'
import { observable, action } from 'mobx';
import { observer } from 'mobx-react/native'

@observer
export default class Country extends Component {
    @observable filterTermValue;
    @observable countriesList = [
      {'slug': 'amsterdam', 'name': 'Amsterdam'},
      {'slug': 'usa', 'name': 'United States'},
      {'slug': 'vienna', 'name': 'Vienna'}
    ];

    render() {
        return (
            <View>
                <Text>Typed Text: {this.filterTermValue}</Text>
                <TextInput placeholder="Start typing country"
                   value={this.filterTermValue}
                   onChange={this.onChangeFilterTerm} />

                {this.countriesList.map(country =>
                    <View key={country.slug}>
                      <Text>{country.name}</Text>
                    </View>
                )}
            </View>
        )
    }

    @action onChangeFilterTerm = (e) => {
        this.filterTermValue = e.target.value;

        this.countriesList.replace(this.countriesList.filter(el => el.name.toLowerCase().indexOf(this.filterTermValue.toLowerCase()) > -1));
    }
}

That's all the logic I have and I can't get it to work. The only thing that works is the country list loads the original array. Once I start typing in the input, the value is undefined and never prints, and the list is never filtered. I also tried async actions and runInAction I even tried computed to return the filtered list, but can't seem to get it to work.

What is the right way to do this in mobX?


回答1:


I saw a few possible problems, so I slightly changed the approach.

Working example

UPDATED Working example. Note this is untested in react-native, but it should work.

The code

@observer
class Country extends React.Component {


    @observable filterTermValue = '';
    @observable countriesList = [
      {'slug': 'amsterdam', 'name': 'Amsterdam'},
      {'slug': 'usa', 'name': 'United States'},
      {'slug': 'vienna', 'name': 'Vienna'}
    ];

    @computed get filtered() {
      let filteredList = this.countriesList.filter(
        t=>t.name.toLowerCase().indexOf(this.filterTermValue)>-1
      );
      if (filteredList.length)
        return filteredList;
      return this.countriesList;
    }

    render() {
        return (
          <div>
              Term: <input placeholder="Start typing country"
                 onKeyUp={this.onChangeFilterTerm} />

              {this.filtered.map(country =>
                  <div key={country.slug}>
                    <p>{country.name}</p>
                  </div>
              )}
          </div>
        )
    }

    @action onChangeFilterTerm = value => {
        this.filterTermValue = value.toLowerCase();
    }
}

React-native gotchyas

Use onChangeText correct signature

jsx:

    <input placeholder="Start typing country"
            onKeyUp={this.onChangeFilterTerm} />

js:

    @action onChangeFilterTerm = value => {
        this.filterTermValue = value.toLowerCase();
    }

Use mobx-react/native

If its still not working, I would double check this:

Dont:

import {observer} from 'mobx-react';

Do:

import {observer} from 'mobx-react/native';


来源:https://stackoverflow.com/questions/37865454/mobx-filter-countries-in-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!