【问题标题】:Call method from view in reducer从减速器的视图中调用方法
【发布时间】:2018-11-30 17:09:33
【问题描述】:

我正在使用 react redux 来制作登录页面和主页。

我在服务器上做认证并调用reducer后,不知道如何才能通过查看我认证并转移到家。 在我的 Reducer 中,当用户和密码无效时,我已经在传递一条消息。

登录服务.js

 export default class LoginService {
    static realizaLogin(login, senha) {
        return dispatch => {
            dispatch(isLoading(true));
            axios.post('account/login', { Login: login, Senha: senha })
                .then(res => {
                    var result = res.data;

                    if (result.IsValid) {
                        dispatch(acessoValido(result.Data));
                    } else {
                        dispatch(acessoInvalido(result.Errors[0].Message));
                    }

                    dispatch(isLoading(false));
                }).catch(error => {
                    dispatch(acessoInvalido(error.message));
                    dispatch(isLoading(false));
                });

        }
    }
}

LoginReducer.js

 export function loginReducer(state = '', action) {

    if (action.type === 'ACESSAR') {
        return action.usuario;
    } else if (action.type === 'ACESSO-INVALIDO') {
        return { mensagemLoginInvalido: action.mensagemLoginInvalido };
    }
    return state;
}

LoginPage.js

class LoginPage extends Component {
  constructor(props) {
    super(props);
    console.log(this.props);

  }

  realizaLogin(event) {
    event.preventDefault();
    this.props.realizaLogin(this.usuario.value, this.senha.value);
  }

  render() {
    return (
      <div>
        <Loading store={this.props.store} />
        <div className="login bg app flex-row align-items-center">
          <Container className="container">
            <Row className="justify-content-center">
              <img src={require('./../../assets/img/brand/logo.png')} alt="Logo do GateClinic" width="300px" height="200px" />
            </Row>
            <Row className="justify-content-center">
              <Col md="6">
                <Card className="p-4">
                  <CardBody>
                    <Form onSubmit={this.realizaLogin.bind(this)}>
                      <InputGroup className="mb-3">
                        <InputGroupAddon addonType="prepend">
                          <InputGroupText>
                            <FontAwesomeIcon icon="building" />
                          </InputGroupText>
                        </InputGroupAddon>
                        <Input type="text" placeholder="Empresa" id="empresa" />
                      </InputGroup>
                      <InputGroup className="mb-3">
                        <InputGroupAddon addonType="prepend">
                          <InputGroupText>
                            <FontAwesomeIcon icon="user" />
                          </InputGroupText>
                        </InputGroupAddon>
                        <Input type="text" placeholder="Usuário" id="usuario" innerRef={input => this.usuario = input} />
                      </InputGroup>
                      <InputGroup className="mb-4">
                        <InputGroupAddon addonType="prepend">
                          <InputGroupText>
                            <FontAwesomeIcon icon="lock" />
                          </InputGroupText>
                        </InputGroupAddon>
                        <Input type="password" placeholder="Senha" id="senha" innerRef={input => this.senha = input} />
                        <FormFeedback className={`${(this.props.mensagemLoginInvalido && this.props.mensagemLoginInvalido !== '' ? 'display-block' : '')} text-align-center`}>
                          {this.props.mensagemLoginInvalido}
                        </FormFeedback>
                      </InputGroup>
                      <Row>
                        <Col xs="6">
                          <Button color="primary" className="px-4" type="submit" >Acessar</Button>
                        </Col>
                        <Col xs="6" className="text-right">
                          <Button color="link" className="px-0">Esqueci minha senha?</Button>
                        </Col>
                      </Row>

                    </Form>
                  </CardBody>
                </Card>
              </Col>
            </Row>
          </Container>
        </div>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return { mensagemLoginInvalido: state.loginReducer.mensagemLoginInvalido }
};
const mapDispatchToProps = dispatch => {
  return {
    realizaLogin: (usuario, senha) => {
      dispatch(LoginService.realizaLogin(usuario, senha));
    }
  }
}

const LoginPageContainer = connect(mapStateToProps, mapDispatchToProps)(LoginPage);

export default withRouter(LoginPageContainer);

【问题讨论】:

  • 理想情况下,您应该存储您的操作状态。并在您的组件中使用存储数据来继续您的逻辑。如果您从 reducer 的视图中添加或调用方法,这将是整个通量架构的反模式。
  • 你能给我举个例子吗?喜欢我的情况吗?
  • 检查我的答案

标签: javascript reactjs redux react-redux react-router


【解决方案1】:

将您的登录 api 响应放入存储中。并在您的组件中使用它。 示例:

const defaultState = {
  loading:false, // you can take advantage of this to show a loader
  loginSuccess:false,
  userData={}
  error:null
}
export function loginReducer(state = defaultState, action) {

    if (action.type === 'ACESSAR') {
        return {...state,loginSuccess:true,userData:action.payload}
    } else if (action.type === 'ACESSO-INVALIDO') {
        return {...state,loginSuccess:false,userData={},error:action.payload}
    }
    return state;
   }

在您的组件中。

class LoginPage extends Component {
  constructor(props) {
    super(props); 
  }

 componentWillRecieveProps(nextProps){
  if(nextProps.loginSuccess){
    // redirect to home page.
  }
  if (nextProps.error) {
    // do something
  }
 }

  render() {
    return (
      ...
      ... your view
      ...
    );
  }
}

const mapStateToProps = state => {
  return { 
    loading:state.loading
    loginSuccess:state.loginSuccess,
    userData=state.userData
    error:state.error
  }
};
const mapDispatchToProps = dispatch => {
  return {
    realizaLogin: (usuario, senha) => {
      dispatch(LoginService.realizaLogin(usuario, senha));
    }
  }
}

const LoginPageContainer = connect(mapStateToProps, mapDispatchToProps)(LoginPage);

export default withRouter(LoginPageContainer);

【讨论】:

  • 太好了。使您的应用程序变得更好。你可以使用一些带有 redux 的中间件来进行 api 调用。比如redux-thunkredux-sagas。如果你喜欢,你也可以投票给答案:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多