React-Redux + Redux-Thunk по функциональному компоненту. Обновление пользовательского интерфейса после получения данных из API - PullRequest
2 голосов
/ 11 апреля 2020

У меня есть функциональный компонент, который извлекает данные из API с использованием приставки.

const useFetching = (someFetchActionCreator) => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(someFetchActionCreator());
    }, [])
}

Компонент:

export function Trips(props) {
    const trips = useSelector(state => state.trips);
    useFetching(fetchTrips)
...
...
}

Thunk:

export const fetchTrips = () => (dispatch) =>
    axios.get("/api/v1/trips")
        .then(response => dispatch(addTrips(response.data)))

export const addTrips = trips => ({
    type: ADD_TRIPS,
    payload: trips
})

Редуктор:

function tripsReducer(state = INITIAL_STATE, action) {
    console.log(action)
    if (action.type === ADD_TRIPS) {
        return Object.assign({}, state, {
            trips: state.trips.concat(action.payload)
        });
    }
    return state
}

Мой редуктор называется. Как я могу обновить пользовательский интерфейс после отправки выбранных данных? Мой рендер больше не вызывается.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

1-й вариант: использование крючков

Вы на самом деле используете React и react-redux крючки. Убедитесь, что вы используете объект trips позже в вашем компоненте. Вот пример использования вашего кода:

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchTrips } from '../tripsActions';

const useFetching = (someFetchActionCreator) => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(someFetchActionCreator());
    }, []);
}

export function Trips(props) {
    const trips = useSelector(state => state.trips);
    useFetching(fetchTrips);

    return (
        <div>
            <p>Total trips: {trips.length}</p>
        </div>
    );
}

2-й вариант: использование connect

Это был способ подключения к состоянию хранилища Redux до того, как они представили перехватчики .

Поскольку вы используете response-redux , это легко сделать с помощью функции connect(). Вы также должны предоставить функцию mapStateToProps() для выбора части данных из хранилища, в которой нуждается ваш компонент, и функцию mapDispatchToProps(), чтобы иметь доступ к действиям, которые будут отправлены.

Вот как ваш Trips компонент будет выглядеть при таком подходе:

import React from 'react';
import { connect } from 'react-redux';
import { fetchTrips } from '../tripsActions';

const mapStateToProps = (state) => {
    return {
        // will be available as props.trips
        trips: state.trips
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        // will be available as props.fetch()
        fetch: () => dispatch(fetchTrips)
    }
}

const function Trips(props) {
    this.props.fetch();
    // some other code. Example:
    return (
        <div>
            <p>Total trips: {this.props.trips.length}</p>
        </div>
    );
}

export default connect(mapStateToProps)(Trips);

mapStateToProps() получает состояние хранилища Redux и возвращает объект, поля которого будут доступны в качестве реквизитов в ваш компонент. Поскольку вы уже используете props.trips, я просто сопоставил это поле с обновленным значением поля trips состояния Redux.

Вызов connect() с вашим компонентом дает вам подключено составная часть. И этот последний должен быть экспортирован, а не оригинальный компонент. Он не создаст другой компонент, поэтому вы будете продолжать использовать компонент Trips в обычном режиме.

Теперь ваш компонент будет перерисован по мере обновления его реквизитов.

Вы можете иметь Изучите документацию о реаги-редуксе, чтобы лучше понять использование функций connect() и mapStateToProps() и mapDispatchToProps().

0 голосов
/ 11 апреля 2020

Вы можете сделать это легко следующим образом:

import React, { 
    useCallback, useEffect 
} from 'react';
import { 
    useSelector, useDispatch 
} from 'react-redux';
// ../ducks for example
import { fetchTrips } from '../ducks';

const function Trips(props) {
    const dispatch = useDispatch();

    useEffect(() => {
       fetchTripsHandler();
    }, []);

    const fetchTripsHandler = useCallback(
        () => dispatch(fetchTrips()),
        []
    );     

    const { trips } = useSelector(state => ({
        trips: state.trips
    }));

    // your other component code
}

С useSelector из react-redux вы не можете использовать connect, mapStateToProps и mapDispatchToProps. После этого ваш компонент будет подключен к магазину.

Вот дополнительная информация о реагирующе-редукционных крючках .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...