问题
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