Состояние Redux сбрасывается при изменении маршрута (я думаю) - PullRequest
1 голос
/ 12 апреля 2020

Я успешно обновляю свое «глобальное состояние» с помощью Redux. Я изменяю языковой индекс моего приложения, используя действие, и оно изменяется в компоненте; однако, когда я перенаправляю на другой компонент, состояние сбрасывается до значения состояния по умолчанию. Помогите, пожалуйста ...

"реагировать": "^ 16.13.1", "реагировать-дом": "^ 16.13.1", "реагировать-редукция": "^ 7.2.0" , "Reaction-router": "^ 5.1.2", "Reaction-router-dom": "^ 5.1.2", "Reaction-scripts": "3.4.1", "redux": "^ 4.0.5 "," redux-thunk ":" ^ 2.3.0 "

/ redux / state. js

export default {
  language: 0,
  sirens: []
}

/ Извлечение / хранение. js

import { createStore, applyMiddleware } from 'redux'
import reducers from './reducers'
import state from './state'
import thunk from 'redux-thunk';

export default createStore(reducers, state, applyMiddleware(thunk))

/ redux / actions. js

export const chLang = (index) => {
  return {
    type: 'CH_LANG',
    value: index
  }
}
export const fetchSirens = () => {
  return  {
    type: 'FETCH_SIRENS',
    value: null
  }
}

export const addSiren = (siren) => {
  return {
    type: 'ADD_SIREN',
    value: siren
  }
}

export const rmSiren = (id) => {
  return {
    type: 'RM_SIREN',
    value: id
  }
}

/ redux / Редукторы. js

import { combineReducers } from "redux";

// language should only store an index
const language = (state = null, action) => {
  switch (action.type) {
    case 'CH_LANG':
      return action.value
    default:
      return state;
  }
}
const sirens  = (state = [], action) => {
  switch (action.type) {
    case 'FETCH_SIRENS':
      return action.value
    case 'ADD_SIREN':
      return [...state, action.value]
    case 'RM_SIREN':
      const sirens = [...state];
      sirens.splice(action.value, 1);
      return sirens;
    default:
      return state;
  }
}


export default(combineReducers({language, sirens}));

Сначала я подумал, что мог случайно изменить исходное состояние моих редукторов, но не думаю, что это так.

/ контейнеры / посадка. js Все контейнеры следуют этой общей схеме:

import { connect } from "react-redux";
import { chLang } from "../redux/actions";
import Landing from '../components/Landing';

const mapStateToProps = state => {
  return {
    language: state.language
  }
}

const mapDispatchToProps = dispatch => {
  return {
    chLang: index => dispatch(chLang(index))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Landing)

/ компоненты / посадка. js

import React from 'react';
import languages from '../languages';
import Button from '@material-ui/core/Button';
import SimpleDialog from '../containers/SimpleDialog'
import blob from '../img/blob-white.png';
import siren1 from '../img/siren-1.png';


const Landing = (props) => {
  const [open, setOpen] = React.useState(false);
  const [selectedValue, setSelectedValue] = React.useState(null);
  const didMountRef = React.useRef(false)


  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = (value) => {
    props.chLang(value)
    setOpen(false);
    setSelectedValue(value);
  };
  React.useEffect(() => {
    if (didMountRef.current) {
      // debugger
      if(props.language !== null){
        // window.location.replace("/hi")
      }
    } else {didMountRef.current = true}
  })

  return (
    <div className="landing">
      <h2 className="sentence">
        <div className="slidingVertical">
          {languages.types.map((lan, i) => <span key={i+1}>{lan.landing[0]}</span>)}
        </div>
      </h2>
      <h1>Siren.</h1>
      <p>You speak {languages.types[props.language].language}</p>
      <div className="landing-img">
        <img id="blob" src={blob} />
        <img id="siren" src={siren1} />
      </div>
      <Button className="landing-bttn" variant="contained" color="primary" onClick={handleClickOpen}>
      <h2 className="sentence sentence-bttn">
        <div className="slidingVertical">
          {languages.types.map((lan, i) => <span className="lang-bttn" key={i+1}>{lan.landing[1]}</span>)}
        </div>
      </h2>
      </Button>
      <SimpleDialog languages={languages} selectedValue={selectedValue} open={open} onClose={handleClose} />
    </div>
  );
}

export default Landing;

проблема возникает, когда я комментирую, что window.location.replace("/hi") и приложение затем загружает компонент "привет". Этот компонент должен отображать текст с указателем языка, который пользователь выбрал из предыдущего компонента; однако язык сбрасывает себя к значению по умолчанию в хранилище (0).

/ components / Hi. js

import React from 'react';
import languages from '../languages';
import Button from '@material-ui/core/Button';
import '../css/hi.css';
import blob from '../img/blob-2.png';
import siren from '../img/siren-1.png'

class Hi extends React.Component {
  state = {
    text: languages.types[this.props.language].hi
  }

  checkSpecialLang = () => {
    switch(this.props.language){
      case 3:
        return'zh'
      case 4:
        return 'hi'
      default:
        console.log('Muffin works! I\'m in quarantine and I\'mma cry ;(')
    }
  }

  handleAgree = () => {
    //     window.location.replace("/track");
  }

  render() {
    // debugger;
    console.log(this.props.language)
    return (
      <div id={this.checkSpecialLang()} className="hi-container">
       <h1>{this.state.text[0]}</h1>
       <img className='siren-img' src={siren} />
       <div className='intro'>
         <p>{this.state.text[1]}</p>
         <img src={blob} />
       </div>
       <p className="question">{this.state.text[2]}</p>
       <Button color='secondary' className="agree-cookies-bttn" variant="contained" onClick={this.handleAgree}>
         <p>{this.state.text[4]}</p>
       </Button>
     </div>
    );
  }
}

export default Hi;

Чего мне не хватает здесь?!

Ответы [ 2 ]

5 голосов
/ 12 апреля 2020

Это потому, что location.replace("/hi") перезагружает все окно, а хранилище резервов также сбрасывается. Чтобы перенаправить пользователя и сохранить состояние редукса без изменений, вам следует направлять между компонентами. Я имею в виду, что вы должны изменить маршрут без перезагрузки всей страницы. Я предлагаю вам использовать реагирующий модуль маршрутизации .

. Вы можете использовать react-router-dom компонент Redirect для перенаправления пользователя без перезагрузки страницы.

Ознакомьтесь с документацией здесь

0 голосов
/ 12 апреля 2020

window.location обновляет все избыточное состояние. Для сохранения состояния используйте компонент «Ссылка» или «Перенаправление» для маршрутизации через компоненты React.

import  { Redirect } from 'react-router-dom'
 <Redirect to='/hi'  />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...