I have a functional ponent that fetches data from an api using redux.
const useFetching = (someFetchActionCreator) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(someFetchActionCreator());
}, [])
}
The ponent:
export function Trips(props) {
const trips = useSelector(state => state.trips);
useFetching(fetchTrips)
...
...
}
The 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
})
The reducer:
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
}
My reducer is called. How can I update the UI after the fetched data have been dispatched? My render is not called again.
I have a functional ponent that fetches data from an api using redux.
const useFetching = (someFetchActionCreator) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(someFetchActionCreator());
}, [])
}
The ponent:
export function Trips(props) {
const trips = useSelector(state => state.trips);
useFetching(fetchTrips)
...
...
}
The 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
})
The reducer:
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
}
My reducer is called. How can I update the UI after the fetched data have been dispatched? My render is not called again.
Share Improve this question edited Apr 11, 2020 at 16:41 vikash chander 471 silver badge11 bronze badges asked Apr 11, 2020 at 10:28 ManosManos 1,5012 gold badges29 silver badges46 bronze badges2 Answers
Reset to default 61st option: Using hooks
You are actually using React
and react-redux
hooks. Make sure you use the object trips
later in your ponent. Here is a sample using your code:
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>
);
}
2nd option: Using connect
This was the way to connect to the Redux store state before they introduced the hooks.
As you are using react-redux this can be easily done by using the connect()
function. You should also provide a mapStateToProps()
function to select the part of the data from the store that your ponent needs and a mapDispatchToProps()
function to have access to the actions to be dispatched.
This is how your Trips
ponent would look like with this approach:
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()
receives the Redux store state and returns an object whose fields will be available as props in your ponent. As you already use props.trips
I simply mapped that field to the updated value of the Redux state's trips
field.
The call to connect()
with your ponent gives you a connected ponent. And that latter should be exported rather than the original ponent. It will not create another ponent so you will continue to use the Trips
ponent normally.
Now your ponent will be re-rendered as its props are being updated.
You can have a look at the react-redux documentation to better understand the use of connect()
and mapStateToProps()
and mapDispatchToProps()
functions.
You can do it easily like that:
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 ponent code
}
With useSelector
from react-redux
you can not use connect
, mapStateToProps
and mapDispatchToProps
.
After that, your ponent will be connected to the Store.
Here is more information about react-redux hooks.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744834216a4596166.html
评论列表(0条)