Вопрос: Как в React + Redux обмениваться данными между компонентами?

Лучший ответ:
Как в React + Redux обмениваться данными между компонентами?
Обмен данными происходит через один общий объект состояния store.
Вам нужно "приконнектить" оба компонента с помощью: connect(mapStateToProps, mapDispatchToProps)(ComponentName)
и тогда они у вас будут слушать изменения в сторе (за счет, того, что вы передадите в функции mapStateToProps), а так же смогут уметь передавать изменения в стор (с помощью dispatch функции, которую вы будете вызывать внутри mapDispatchToProps).
К сожалению, объяснение очень сухое и может быть не понятным, но и ваш вопрос выглядит как: ребята, объясните мне (желательно кодом) как работает redux. Лучше пройти какоий-нибудь туториал внимательно и такой вопрос сам по себе отпадет.
Если немного упростить, то вам нужно будет:
из компонента Settings вызвать action creator (через dispatch)
в компоненте User это дело поймать (поймаете с помощью редьюсера, на который будет "натравлена" функция mapStateToProps)

Худший ответ:
По-хорошему, надо код запроса писать вне компонента, а в компонент передавать action инициирующий запрос. Хорошим вариантом будет использовать для этого  redux-saga. В Settings вы должны только запрашивать данные и как только они приходят получать их где хотите из store.
Примерный код:
Редьюсер и action creators:const FETCH_USER_DATA_REQUEST = 'FETCH_USER_DATA_REQUEST';
const FETCH_USER_DATA_SUCCESS = 'FETCH_USER_DATA_SUCCESS';
const FETCH_USER_DATA_FAIL = 'FETCH_USER_DATA_FAIL';

export const fetchUserData = () => ({
  type: FETCH_USER_DATA_REQUEST,
});

export const fetchUserDataSuccess = data => ({
  type: FETCH_USER_DATA_SUCCESS,
  payload: data,
});

export const fetchUserDataFail = () => ({
  type: FETCH_USER_DATA_FAIL,
});

const initialState = {
  data: {},
  isLoading: true,
  isError: false,
};

export default (state = initialState, action) => {
  const { type, payload } = action;

  switch (action) {
    case FETCH_USER_DATA_REQUEST:
      return {
        ...state,
        isLoading: true,
      };
   
    case FETCH_USER_DATA_SUCCESS:
      return {
        ...payload,
        isLoading: false,
        isError: false,
      };

   case FETCH_USER_DATA_FAIL:
     return {
       ...state,
       isLoading: false,
       isError: true,
     };
   
   default: 
      return state;
  }
};
Сага. По вызову функции fetchUserData, тут произойдет вызов api, в случае успеха в store придут данные, в случае ошибки isError примет значение true:import { call, put, takeLatest } from 'redux-saga/effects';
import {
  FETCH_USER_DATA_REQUEST,
  fetchUserDataSuccess,
  fetchUserDataFail,
} from '../ducks/userDucks';
import { fetchUserData } from '../api';

export function* fetchUserDataSaga() {
  try {
    const { data } = yield call(fetchUserData);

    yield put(fetchUserDataSuccess(data));
  } catch (error) {
    yield put(fetchUserDataFail());
  }
}

export default function* watchFetchUserDataSaga() {
  yield takeLatest(FETCH_USER_DATA, fetchUserDataSaga);
}
Для выборки из store лучше использовать selector:export const userDataSelector = state => state.userData;
Тут провайдим данные пользователя в User:import User from './User';
import { userDataSelector } from '../selectors';

const mapStateToProps = state => ({
  userData: userDataSelector(state),
});

export default connect(mapStateToProps)(User);
Тут провайдим данные пользователя и fetchUserData в Settings:import Settings from './Settings';
import { userDataSelector } from '../selectors';
import { fetchUser } from '../ducks/userDucks';

const mapStateToProps = state => ({
  userData: userDataSelector(state),
});

const mapDispatchToProps = {
  fetchUserData,
};

export default connect(mapStateToProps, mapDispatchToProps)(Settings);