Невозможно изменить избыточное логическое состояние - PullRequest
0 голосов
/ 18 сентября 2018

Я немного растерялся, проблема в том, что действие defineAvailableTouch и обновление состояния связаны с ним.

Вот мой код:

Actions / index.js

 import {
    ANIMATE_HELLO,
    HANDLE_SCROLL,
    IS_TOUCH_DEVICE,
    SET_ABOUT_TOP,
    SET_CONTACT_TOP,
    SET_PORTFOLIO_TOP
} from "../Constants/ActionTypes";

export const animateHello = hello => ({
    type: ANIMATE_HELLO,
    payload: hello
});

export const handleScroll = scrollDelta => ({
    type: HANDLE_SCROLL,
    payload: scrollDelta
});

export const defineTouchAvailable = isTouchDevice => ({
    type: IS_TOUCH_DEVICE,
    payload: isTouchDevice
});

export const setAboutTop = aboutTop => ({
    type: SET_ABOUT_TOP,
    payload: aboutTop
});

export const setContactTop = contactTop => ({
    type: SET_CONTACT_TOP,
    payload: contactTop
});

export const setPortfolioTop = portfolioTop => ({
    type: SET_PORTFOLIO_TOP,
    payload: portfolioTop
});

Reducers / index.js

 import {
    IS_TOUCH_DEVICE,
 } from "../Constants/ActionTypes";
 import { initialState } from "../Constants/InitialState/InitialState";

 export const rootReducer = (state = initialState, action) => {
     switch(action.type) {
          case ANIMATE_HELLO:
              return {
                  ...state,
                  hello: action.payload
              };
          case HANDLE_SCROLL:
              return {
                  ...state,
                  scrollState: action.payload
          };
          case IS_TOUCH_DEVICE:
             console.log(action.payload); //!!!!!! THIS PRINTS EXPECTED VALUE !!!!!!!!!!
             return {
                  ...state,
                  isTouchDevice: action.payload
          };
          case SET_ABOUT_TOP:
              return {
                   ...state,
                   aboutTop: action.payload
          };
          case SET_CONTACT_TOP:
              return {
                  ...state,
                  contactTop: action.payload
          };
          case SET_PORTFOLIO_TOP:
              return {
                  ...state,
                  portfolioTop: action.payload
              };
          default:
              return state
      }
 };

InitialState.js

export const initialState = {
    scrollState: 0,
    hello: 'H',
    aboutTop: 0,
    portfolioTop: 0,
    contactTop: 0,
    isTouchDevice: true
};   

App.js

import React, { Component } from 'react';
import { connect } from "react-redux";

import About from "./Containers/About";
import Contact from "./Containers/Contact";
import Page from "./Containers/Page";
import Projects from "./Containers/Projects";
import {
    defineTouchAvailable,
    handleScroll
} from "./Actions";

window.onbeforeunload = () => {
    handleScroll(0);
    document.documentElement.scrollTop = 0;
};

const mapStateToProps = state => {
    return {
        isTouchDevice: state.isTouchDevice
    }
};

const dispatchStateToProps = dispatch => {
    return {
        defineTouchAvailable: isTouchDevice => 
dispatch(defineTouchAvailable(isTouchDevice)),
        handleScroll: scrollState => dispatch(handleScroll(scrollState))
    }
};

class App extends Component {

    componentDidMount() {
        try {
            document.createEvent('touchevent');
            this.props.defineTouchAvailable(true);
        } catch(e) {
            this.props.defineTouchAvailable(false);
        }

        console.log(this.props.isTouchDevice); //!!!!!!!!!!!!!!! THIS ALWAYS PRINTS VALUE FROM initialState !!!!!!!!!!!!!!

        if(this.props.isTouchDevice) {
            document.documentElement.scroll(0, 1);
        }

        document.addEventListener('scroll', () => {
            if (document.documentElement.scrollTop === 0) {
                this.props.handleScroll(0);
            }
        });
    }

    render() {
        return (
            <div>
                <Page/>
                <Projects/>
                <About/>
                <Contact/>
            </div>
        );
    }
}

export default connect(mapStateToProps, dispatchStateToProps)(App);

Я действительно не могу понять, что здесь не так.

Как я уже прокомментировал

  • reducer console.log печатает правильное значение, которое, как ожидается, будет присвоено моему состоянию (поле isTouchDevice), но

  • после назначения в диспетчерском действии ничего не меняется - это всегда значение из initialState.

Может кто-нибудь объяснить мне?Я неправильно изменяю свое состояние притока?Тогда почему другие действия работают так, как они ожидают?

1 Ответ

0 голосов
/ 18 сентября 2018

Обновленное значение isTouchDevice будет доступно в componentDidUpdate, render или componentWillReceiveProps, а не в componentDidMount.

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

Примечание: componentWillReceiveProps устарело, лучше его не использовать.

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