React Native реализует данные JSON в ListView

У меня проблема с реализацией данных API в ListView. Я получил JSON с помощью Axios.

export function fetchRateService() {
  return function(dispatch) {
    axios.get(RATE_URL)
        .then(response => {
            dispatch({
                type: FETCH_RATE_SERVICE,
                payload: response.data
            });
        })
        .catch((error) => {
            console.log(error);
        })
  }
}

Редуктор. Я добавил данные о ставках в массив

import {
FETCH_RATE_SERVICE
} from '../actions/types';

const INITIAL_STATE = {
  base: '',
  date: '',
  rates: []
};
export default (state = INITIAL_STATE, action) => {
 switch (action.type) {
    case FETCH_RATE_SERVICE:
        return { 
            ...state, 
            base: action.payload.base,
            date: action.payload.date,
            rates: [ ...state.rates, action.payload.rates ]
        };
    default:
        return state;
 }
};

Это компонент

class ConturyList extends Component {

componentWillMount() {
    this.props.fetchRateService();
    this.createDataSource(this.props);
}

createDataSource({rates}) {
    const ds = new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
    });
    this.dataSource = ds.cloneWithRows(rates);
}

renderRow(rate) {
    return <ListItem rate={rate} />
};


render() {
    console.log(this.props);
    const { CardSectionStyle, textStyle, containerStyle } = styles;
    const { visible, closeModal } = this.props;
    return (
        <Modal
            visible={visible}
            transparent={false}
            animationType="slide"
            onRequestClose={() => {this.props.closeModal()}}
        >
            <ListView
                enableEmptySections
                dataSource={this.dataSource}
                renderRow={this.renderRow}
            /> 
        </Modal>
    );
  }
}

const mapStateToProps = state => {
  return { 
    rates: state.rateService.rates,
    date: state.rateService.date,
    base: state.rateService.base
  };
 }

 export default connect(mapStateToProps, { fetchRateService } )(ConturyList);

Проблема в том, что я могу видеть данные реквизита, используя console.log(this.props); введите здесь описание изображения Я потратил более 3 дней, чтобы понять, почему это так не работает. Я пытался добавить map() к renderRow(rate) { return rate.map((data) => { return <ListItem rate={data} /> };, но это не сработало. Весь внутренний код находится в одном объекте. Нужно ли разделять данные запятыми? Ценю, что вы помогаете. Спасибо

ОБНОВЛЕНИЕ Поэтому я пытаюсь реализовать FlatList вместо использования ListView. Проблема в данных JSON. введите здесь описание изображения. Я хочу внедрить ключ CountryCurrencyCode (AUD, JPN и т. д.) в FlatList. Так как ставки — это объект внутри объекта, я добавил объект ставки в массив (редуктор). Но this.props.rates[0] нельзя реализовать в свойстве данных FlatList. Какой метод я могу попробовать? Я ничего не могу придумать. Я мог бы распечатать ключ, используя map(), когда ставки являются объектом, а затем я не могу реализовать его в FlatList.


person MachoBoy    schedule 28.07.2017    source источник


Ответы (1)


Я бы рекомендовал переключиться на новый компонент FlatList вместо ListView. FlatList просто принимает массив данных для гидратации.

Инициировать this.state.datasource как пустой массив

constructor(props) {
  super(props);
  this.state = {
    dataSource: [],
  }
}

Извлеките свои данные и увлажните this.state.dataSource из вашего редуктора/действия Redux.

ComponentDidMount(){
  this.props.fetchRateService();
  var myData = this.props.rates[0];
  this.setState({
    dataSource:myData
  )}
}

Теперь, когда ваш this.state.dataSource установлен, мы можем заполнить FlatList

<FlatList
  data={this.state.dataSource}
  renderItem={({item})=>this.renderRow(item)} 
/>

Плоский список выдаст предупреждение об экстракторе ключей

Добавьте эту строку ниже в компонент FlatList. Вам нужно будет изменить «item.key», чтобы он соответствовал вашему собственному уникальному дочернему элементу. Вы можете просто оставить его пока для развития.

keyExtractor={item => item.key}

Вы должны увидеть свои данные сейчас! Имейте в виду, вам не нужно устанавливать this.state.dataSource. Это просто то, как я это делаю. Вместо этого вы можете подключить массив this.props.rates непосредственно к FlatList. Ознакомьтесь с документами FlatList, чтобы узнать обо всех возможностях, с которыми вы можете работать. Это. Надеюсь это поможет!

person gbland777    schedule 29.07.2017
comment
Спасибо за ответ с руководством. Я новичок в реакции и никогда не слышал о FlatList до этого ответа. Я читаю документ FlatList прямо сейчас. Я попытаюсь собрать его с помощью FlatList и опубликую свой результат. Еще раз спасибо!! - person MachoBoy; 29.07.2017
comment
Когда я попытался с помощью приведенного выше руководства, console.log(this.state.dataSource) показал мне пустой массив после рендеринга. Я обнаружил, что var myData = this.props.rates не работает (не определено), поэтому в свойстве данных FlatList data={this.props.rates} показал мне ошибку с объектами, которые недействительны в качестве дочернего элемента React (найдено: объект с ключами {...countrycurrencycode}. Я думал, что свойство keyExtractor позаботится ключей. - person MachoBoy; 29.07.2017
comment
Ааа, теперь я вижу, что происходит. Ваш this.props.rates — это объект внутри объекта. Чтобы получить фактический массив, вам нужно будет либо переписать часть вашего редуктора, либо извлечь его с помощью this.props.rates[0]. Попробуйте console.log(this.props.rates[0]);. Вы должны увидеть только свой массив. Что касается keyExtractor, я бы предложил просто удалить его на время, пока мы не заработаем ваш список. - person gbland777; 29.07.2017
comment
Я знал, что console.log(this.props.rate[0]) выведет все значения в массиве, но реализовать его в свойстве данных не получилось. Это нулевое значение. Я не знаю почему. поэтому я попытался сохранить объект в ставках на редукторе. добавьте метод для компонента renderRow() { {Object.keys(this.props.rates).map((countryCode) => { console.log(countryCode); return <ListItem rate={countryCode} /> })} }, он выводит ключи на консоль. звучит отлично до сих пор. но проблема в том, что я не могу использовать его для свойства данных FlatList, потому что это не массив. хм.... - person MachoBoy; 01.08.2017