@km170682tvv

Почему в React/Redux state обновляется глобально, но не обновляется в компонентах?

При загрузке родительского компонента я делаю запрос к бэкэнду (Laravel) чтобы проверить авторизован ли пользователь и получить его данные. После получения ответа я сохраняю эти данные в state store'a с помощью функции dispatch. Но в компонентах (ни в дочерних, ни в самом обновления не происходит. Я проверяю this.props.state в любом методе компонента и везде получаю только изначально состояние, без полученных данных. При этом глобально данные обновились, я вижу их в консоли с помощью подписки (store.subscrube()).
Что я делаю не так?

store.js
import { createStore } from 'redux';

const store = createStore(reducer);

function reducer(state = {is_auth : false}, action) {
  if (action.type === 'GET_AUTH') {
    state.auth = action.payload;
    state.is_auth = true;
  }
  return state;
}

export default store;

store.subscribe(() => console.info(store.getState()))


App.js
import React, { Component }  from 'react';
import { connect } from 'react-redux';
import Main from './Main';
import Navigation from './Navigation';


class App extends Component {

	authRequest() {
		console.log('auth: ' + Date.now())
		if (this.checkToken()) {
			axios.get('/api/current',{
				headers: {'Authorization' : 'Bearer ' + sessionStorage.getItem('token')}
			})
			.then((response) => {
				this.props.onGetAuth(response.data);
			})
			.catch((error) => {
				console.log(error);
			})
		}
	}

	checkToken() {
		return sessionStorage.getItem('token') && Date.parse(sessionStorage.getItem('token_expires')) > Date.now();
	}

	render() {

		if (this.props.is_auth == false) this.authRequest();

		return ( 
			<div>
			<Navigation /> 
			<Main /> 
			</div> 
		);
	}
}

const mapStateToProps = state => {
  return state
}

const mapDispatchToProps = dispatch => {
  return {
    onGetAuth : (auth) => {
			dispatch({ type: 'GET_AUTH', payload: auth })
		}
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);
  • Вопрос задан
  • 1219 просмотров
Решения вопроса 1
Gimir
@Gimir
JavaScript dev
Проблема кроется здесь

function reducer(state = {is_auth : false}, action) {
  if (action.type === 'GET_AUTH') {
    state.auth = action.payload;
    state.is_auth = true;
  }
  return state;
}

Вы мутируете state, redux так работать не будет, нужно всегда возвращать новый стейт, читайте документацию к редаксу. Вот так попробуйте:
function reducer(state = {is_auth : false, auth: null}, action) {
  if (action.type === 'GET_AUTH') {
    return {
       auth: action.payload,
       is_auth: true
    }
  }
  return state;
}

И следите чтобы дефолтный стейт имел все задуманные свойства.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Zhanna_K
@Zhanna_K
in progress
Не знаю в чем конкретно проблема, но из того, что я увидела:
1) асинхронные запросы к api должны быть в методе ComponentDidMount(), у вас они в рендере, так делать не следует
2) reducer должен быть "чистой функцией", то есть создавать глубокую копию state, и именно её уже менять и возвращать

PS. Экспертом по реакту не являюсь, сама в процессе обучения
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы