Redux MapDispatchToProps не работает - PullRequest
0 голосов
/ 14 октября 2019

Итак, я новичок в Redux и пытаюсь заставить эту базовую модель работать так, чтобы я мог быстро работать над небольшим личным проектом, я все настроил и у меня нет ошибок, но я пытаюсь проверить и свою функциюне работает, поэтому я надеялся, что кто-то может указать на то, что я пропустил.

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

Мой store.js выглядит так

import rootReducer from "./reducers";
import thunk from "redux-thunk";
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;

Я использовал ОбъединениеReducers в моей папке index.js в редукторах, а auth: указывает на файл authReducer.js, которыйthis


const INIT_STATE = {
  email: "",
  password: "",
  isLoggedIn: "false"
};

export default (state = INIT_STATE, action) => {
  switch (action.type) {
    case IS_LOGGED_IN_CHANGE:
      console.log(action);
      return {
        isLoggedIn: action.value
      };
    default:
      return state;
  }
};

Теперь, к чему я стремлюсь, это иметь кнопку, которая изменяет исходное состояние «IsLoggedIn» на истинную строку вместо ложной, я зашел в свою папку действий и сделалauthActions.js, который выглядит так

import { IS_LOGGED_IN_CHANGE } from "../actions/types";
import store from "../store";

export const isLoggedInChange = value => {
  return dispatch => {
    dispatch({
      type: IS_LOGGED_IN_CHANGE,
      value
    });
  };
};

И, наконец, я хочу показать вам свою страницу компонента, которая показывает все это, Это выглядит так

import { connect } from "react-redux";

import styles from "./Landing.module.css";
import { isLoggedInChange } from "../../actions/authActions";

class Landing extends Component {
  makeTrue = () => {
    isLoggedInChange("true");
  };

  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
  }
  render() {
    return (
      <div className={styles.background}>
        <button onClick={this.makeTrue}>MAKE TRUE</button>
        {this.props.isLoggedIn}
      </div>
    );
  }
}

const mapStateToProps = state => ({
  isLoggedIn: state.auth.isLoggedIn
});

const mapDispatchToProps = dispatch => ({
  isLoggedInChange: value => dispatch(isLoggedInChange(value))
});

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

Можете ли вы сказать, если яупал что-нибудь сделать? почему кнопка не меняет состояние магазина? ТИА

Ответы [ 3 ]

1 голос
/ 14 октября 2019

Состояние Redux является неизменным, поэтому вам нужно вернуть новый экземпляр состояния, измените состояние вашего редуктора на следующее.

export default (state = INIT_STATE, action) => {
   switch (action.type) {
    case IS_LOGGED_IN_CHANGE:
       console.log(action);
       return Object.assign({}, state, {
         isLoggedIn: action.value
       });
    default:
      return state;
  }
};

Основное различие -

return Object.assign({}, state, {
         isLoggedIn: action.value
       });

Object.assign в том виде, в котором я его здесь использую, объединяет объект состояния в совершенно новый объект. Проверьте неизменяемость в редукционных редукторах, и я бы порекомендовал добавить redux-immutable-state-invariant в качестве пакета dev, он может определить, когда вы непосредственно изменяете состояние, и помочь указать на ошибки, подобные этой

1 голос
/ 14 октября 2019

Две проблемы здесь. Вы называете своего создателя действия напрямую, а не props.isLoggedInChange

  makeTrue = () => {
    this.props.isLoggedInChange("true");
  };

И вам нужно распространить старое состояние внутри вашего действия

case IS_LOGGED_IN_CHANGE:
  console.log(action);
  return {
    ...state,
    isLoggedIn: action.value
  };

Не в этом ли смыслмой mapDispatchToProps, чтобы я мог использовать функцию сразу же, как я делал

Да, проблема в том, что mapDispatchToProps вставьте функцию (или несколько функций), заключенную в dispatch, в ваш props.

import { actionCreator } from './actions

const mapDispatchToProps = dispatch =>({
    actionCreator : () => dispatch(actionCreator)
})  

Теперь у вас есть два actionCreator, один глобально доступен в области действия (который является вашим создателем действия) и props.actionCreator, который является оригинальным создателем действия, завернутым в dispatch. Поэтому, когда вы вызываете actionCreator() изнутри вашего компонента, он не будет выдавать никаких ошибок (потому что в области видимости есть функция с именем actionCreator, но вы будете вызывать неправильную функцию, правильная расположена в props.actionCreator.

Зачем мне распространять состояние?

Редуктор - это чистая функция, которая получает state и action и возвращает новое состояние. Когда вы просто возвращаете

return {
    isLoggedIn : true
}

Вы фактически перезаписываете исходное состояние (которое содержит другие свойства), поэтому сначала вам нужно spread исходное состояние, чтобы сохранить его структурную целостность, и они перезаписывают свойства, которые выхочу

return{
   ...state,
   isLoggedIn : !state.isLoggedIn
}
0 голосов
/ 14 октября 2019

Возвращает состояние с новым значением для isLoggedIn. Используйте редуктор так:

case IS_LOGGED_IN_CHANGE:
  console.log(action);
  return {
    ...state,
    isLoggedIn: action.value
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...