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

Допустим есть компонент User который принимает данные и обрабатывает их.
Эти данные приходят асинхронно в компонент Settings.

export default class Root extends Component {
    render() {
        return (
            <Provider store={store}>
                    <User /> // передать данные сюда
                    <Settings /> //от сюда
            </Provider>
        )
      }
  }
 

ReactDOM.render( <Root />, document.getElementById( 'root' ) );


Как это можно сделать? Или как принято делать в подобных проблемах?
  • Вопрос задан
  • 2734 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
По-хорошему, надо код запроса писать вне компонента, а в компонент передавать 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);
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
maxfarseer
@maxfarseer
https://maxpfrontend.ru, обучаю реакту и компании
Как в React + Redux обмениваться данными между компонентами?

Обмен данными происходит через один общий объект состояния store.
Вам нужно "приконнектить" оба компонента с помощью:
connect(mapStateToProps, mapDispatchToProps)(ComponentName)

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

К сожалению, объяснение очень сухое и может быть не понятным, но и ваш вопрос выглядит как: ребята, объясните мне (желательно кодом) как работает redux. Лучше пройти какоий-нибудь туториал внимательно и такой вопрос сам по себе отпадет.

Если немного упростить, то вам нужно будет:
из компонента Settings вызвать action creator (через dispatch)
в компоненте User это дело поймать (поймаете с помощью редьюсера, на который будет "натравлена" функция mapStateToProps)
Ответ написан
RomReed
@RomReed
JavaScript, Flutter, ReactNative, Redux, Firebase
Ну считаю что правильно будет если вы подключите редукс, положите данные в Store из settings а затед возьмете эти данные в компоненте User.
Но можно написать функцию которая будет отправлять данные в родительский state а потом из родительского стейта в другой компонент. Но первый вариант правильнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы