Как я могу отправить изменение состояния на избыточное при вызове его из функции внутри компонента? - PullRequest
0 голосов
/ 05 января 2019

Я все еще довольно новичок в Javascript и React, и пытаюсь внедрить Redux в мой проект админ-сайта.

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

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

В некотором роде мини-вопрос: я вижу, что многие люди рекомендуют не connect все компоненты к редуксу store, но никогда не уверены, почему для этого я должен просто поместить IP-адрес в локальный хранилище и clear() это каждый раз, когда пользователь пытается войти? В любом случае, я хочу, по крайней мере, успешно внедрить Redux, чтобы при необходимости использовать его в будущем.

Проблема в том, что у меня есть некоторые buttons, которые СДЕЛАЮТ успешно изменить состояние в хранилище резервов, а затем другие компоненты после входа в систему делают запросы к этому конкретному серверу. Но в раскрывающемся списке, который я только что вставил <Select />, при любом изменении он вызывает функцию внутри моего компонента, функция запускается, и все записывается на консоль, как и должно быть, ЗА ИСКЛЮЧЕНИЕМ, что состояние в избыточном хранилище больше не меняется , но, насколько я понимаю, он все еще использует тот же вызов реагировать-редукса connect, как и buttons, который делал

Итак, у меня есть actions.js:

export const DEV_ADDRESS = 'dev.example.com';
export const STAGE_ADDRESS = 'stage.exmaple.com';
export const PROD_ADDRESS = 'prod.example.com';

export function devServer() {
  return {
    type: DEV_ADDRESS,
  };
}

export function stageServer() {
  return {
    type: STAGE_ADDRESS,
  };
}

export function prodServer() {
  return {
    type: PROD_ADDRESS,
  };
}

И мой reducer.js:

import {
  DEV_ADDRESS,
  STAGE_ADDRESS,
  PROD_ADDRESS,
} from '../actions/serverActions';

const initialState = {
  serverAddress: PROD_ADDRESS,
};

export default function (state = initialState, action) {
  switch (action.type) {
    case DEV_ADDRESS:
      console.log("REDUCER DEV");
      return {
        ...state,
        serverAddress: DEV_ADDRESS
      };
    case STAGE_ADDRESS:
      console.log("REDUCER STAGE");
      return {
        ...state,
        serverAddress: STAGE_ADDRESS
      };
      case PROD_ADDRESS:
        console.log("REDUCER PROD");
        return {
          ...state,
          serverAddress: PROD_ADDRESS
        };
    default:
      return state;
  }
}

Сейчас у меня LogIn.jsx:

import React, { PureComponent } from 'react';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { Button } from 'reactstrap';
import axios from 'axios';
import Select from 'react-select';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import EyeIcon from 'mdi-react/EyeIcon';
import Logo from '../../shared/img/logo/logo_light_2.svg';
import * as serverActionTypes from '../../redux/actions/serverActions';


class LogIn extends PureComponent {
  static propTypes = {
    handleSubmit: PropTypes.func.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      showPassword: false,
      in: false,
    };
  }

  componentDidMount() {
    localStorage.clear();
  }

  .
  .
  .
  .
  .

  handleEmailChange(event) {
    this.setState({ email: event.target.value })
  }

  handlePasswordChange(event) {
    this.setState({password: event.target.value})

  handleChange = (selectedOption) => {
    console.log("$$$$$$$$$$$$");
    console.log(selectedOption.value);
    console.log(this.props)
    if (selectedOption.value === serverActionTypes.devServer().type) {
      console.log("handle dev change");
      {this.props.onSelectDevServerAddress}
    }
    else if (selectedOption.value === serverActionTypes.stageServer().type) {
      console.log("handle stage change");
      {this.props.onSelectStageServerAddress}
    }
    else if (selectedOption.value === serverActionTypes.prodServer().type) {
      console.log("handle prod change");
      {this.props.onSelectProdServerAddress}
    }
  };

  render() {
    const { handleSubmit } = this.props;

    if (this.state.in === true) {
      return <Redirect to={{pathname: "/dashboard"}} />;
    }

    return (
      <div className="account">
        <div className="account__wrapper">
          <div className="account__card" align="center">
            <img
              src={Logo}
              alt="example-logo"
              height="35"
              style={{marginBottom: '50px'}}
            />
          </div>
          <div className="account__card">
            <form className="form form--horizontal" onSubmit={handleSubmit}>
              <div className="form__form-group">
                <span className="form__form-group-label">E-mail</span>
                <div className="form__form-group-field">
                  <Field
                    name="email"
                    component="input"
                    type="email"
                    placeholder="example@mail.com"
                    value={this.state.email}
                    onChange={this.handleEmailChange.bind(this)}
                  />
                </div>
              </div>
              <div className="form__form-group">
                <span className="form__form-group-label">Password</span>
                <div className="form__form-group-field">
                  <Field
                    name="password"
                    component="input"
                    type={this.state.showPassword ? 'text' : 'password'}
                    placeholder="Password"
                    value={this.state.password}
                    onChange={this.handlePasswordChange.bind(this)}
                  />
                  <button
                    className={`form__form-group-button${this.state.showPassword ? ' active' : ''}`}
                    onClick={e => this.showPassword(e)}
                  ><EyeIcon />
                  </button>
                </div>
              </div>
              <div className="form__form-group">
                <span className="form__form-group-label">Server</span>
                <div className="form__form-group-field">
                  <div className="form__form-group-input-wrap">
                    <Select
                      name='server_address_selector'
                      value='prod.example.com'
                      onChange={this.handleChange}
                      options={[
                        { value: 'dev.example.com', label: 'Dev' },
                        { value: 'stage.example.com', label: 'Stage' },
                        { value: 'prod.example.com', label: 'Prod' },
                      ]}
                      clearable={false}
                      className="form__form-group-select"
                    />
                  </div>
                </div>
              </div>

              <Button
                color="success"
                onClick={this.onLogin.bind(this)}
                outline>
                Sign In
              </Button>
              <Button
                color="success"
                onClick={this.props.onSelectDevServerAddress}
                outline>
                DEV
              </Button>
              <Button
                color="success"
                onClick={this.props.onSelectStageServerAddress}
                outline>
                STAGE
              </Button>
              <Button
                color="success"
                onClick={this.props.onSelectProdServerAddress}
                outline>
                PROD
              </Button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    ipAddress: state.server
  }
}

const mapDispatchToProps = dispatch => ({
  onSelectDevServerAddress: () => dispatch(serverActionTypes.devServer()),
  onSelectStageServerAddress: () => dispatch(serverActionTypes.stageServer()),
  onSelectProdServerAddress: () => dispatch(serverActionTypes.prodServer()),
});

LogIn = connect(
  mapStateToProps,
  mapDispatchToProps
)(LogIn);

export default reduxForm({
    form: 'log_in_form'
})(LogIn);

1 Ответ

0 голосов
/ 05 января 2019

Проблема в том, что вы не отправляли никаких действий на редуктор. Вы должны фактически вызвать функции из mapStateToDispatch, чтобы выполнить некоторое обновление состояния хранилища избыточных данных.

В коде ниже:

handleChange = (selectedOption) => {
console.log("$$$$$$$$$$$$");
console.log(selectedOption.value);
console.log(this.props)
if (selectedOption.value === serverActionTypes.devServer().type) {
  console.log("handle dev change");
  {this.props.onSelectDevServerAddress}
}
else if (selectedOption.value === serverActionTypes.stageServer().type) {
  console.log("handle stage change");
  {this.props.onSelectStageServerAddress}
}
else if (selectedOption.value === serverActionTypes.prodServer().type) {
  console.log("handle prod change");
  {this.props.onSelectProdServerAddress}
}
};

Вместо того, чтобы делать что-то вроде этого: {This.props.onSelectProdServerAddress}

Вы должны вызвать эту функцию: this.props.onSelectProdServerAddress ();

Теперь ваше действие будет отправлено редуктору.

...