gpt4 book ai didi

javascript - 根据 Redux 所做的状态变化来 react 事件监听器

转载 作者:行者123 更新时间:2023-11-30 09:37:50 27 4
gpt4 key购买 nike

下午好

当我尝试根据状态变化重定向我的应用程序的用户时,我在使用 React 和 Redux 时遇到了一些困难。

在高层次上:当状态中的 user 对象填充了从 home //student/的信息时,我希望我的应用程序的路由发生变化:用户名

现在我已经以一种古怪的方式完成了这项工作。

在我的 Login 组件中,我使用 componentDidUpdate 生命周期 Hook 来监听并在来 self 的第 3 方 API 的访问 token 传回客户端时分派(dispatch)操作快速服务器。

import React from "react";

import LoginForm from "../minor/LoginForm";

const Login = React.createClass({

componentDidUpdate(){
const {success, access_token} = this.props.loginStatus;

if (success === true && access_token !== null){
console.log("It worked getting your data now...");
this.props.getUserData(access_token);
} else if (success === false || access_token === null){
console.log("Something went wrong...");
}

},
render(){

return(

<div className="loginComponentWrapper">
<h1>Slots</h1>
<LoginForm loginSubmit={this.props.loginSubmit}
router={this.props.router}
user={this.props.user} />
<a href="/register">New User?</a>
</div>
)
}
});

请注意,我正在将 routeruser 传递到我的 LoginForm 组件。我这样做是为了使用另一个 componentDidUpdate,我在 router 上使用 .push 方法,如下所示:

import React from "react";

const LoginForm = React.createClass({


componentDidUpdate(){
const {router, user} = this.props;

if (user.username !== null){
router.push(`/student/${user.username}`);
}
},


render(){

return(
<div className="loginWrapper">
<div className="loginBox">
<form className="loginForm" action="">
<input ref={(input) => this.username_field = input} type="text" placeholder="username" defaultValue="kitties@kit.com" />
<input ref={(input) => this.password_field = input} type="text" placeholder="password" defaultValue="meowMeow3" />
<button onClick={this.loginAttempt}>Login</button>
</form>
</div>
</div>
)
}

});

当然可以,但我确定这是一个过于复杂的解决方案,而不是最佳实践。我已经尝试在我的 Login 组件中添加自定义监听器方法,但我从未成功触发它,而是我的应用程序陷入了循环。

有没有一种方法可以让我使用 Redux 做到这一点并使我的组件更整洁,或者以更有效的方式利用 componentDidUpdate

一如既往,我会感谢一些更有经验的人关注我的问题,并期待一些反馈!

谢谢

更新

App.js

import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import * as actionCreators from "../actions/userActions.js";

import StoreShell from "./StoreShell.js";

function mapStateToProps(state){
return{
loginStatus: state.loginStatus,
user: state.user
}
}

function mapDispatchToProps(dispatch){
return bindActionCreators(actionCreators, dispatch)
}

const App = connect(mapStateToProps, mapDispatchToProps)(StoreShell);

export default App;

该组件将我所有的 redux 内容和状态数据“散布”到名为 StoreShell 的容器组件中,该组件又将所有数据传递给构成 UI 的元素的 Prop ,例如 Login LoginForm 我是不是走了太多步?

StoreShell.js

import React from "react";

const StoreShell = React.createClass({

render(){

return(

<div className="theBigWrapper">
{React.cloneElement(this.props.children, this.props)}
</div>

)

}
})

export default StoreShell;

最佳答案

有几件事可以使登录流程更易于管理、推理和整理您的组件。首先是几个一般点:

我不确定为什么要在两个组件之间划分登录逻辑?惯用的 React/Redux 方法是拥有一个处理逻辑的容器组件和一个处理表示的表示组件。目前,这两个组件各做一点。

您不需要在组件中上下传递 props.router。 React router 提供了一个 HOC,它将路由器作为 props 提供,称为 withRouter( docs here )。您只需将一个组件包装在 withRouter 中,props.router 就可用了——其他一切都保持不变。

export default withRouter(LoginForm);

我个人的感觉是 URI 是应用状态的一部分,因此它应该在商店中维护并通过调度操作进行更新。有一个破解库可用于执行此操作 - react-router-redux .设置完成后,您可以将 push 方法传递给您的组件(或其他地方......请参阅下一点)以进行导航:

import { push } from 'react-router-redux';
import { connect } from 'react-redux';

const NavigatingComponent = props => (
<button onClick={() => props.push('/page')}>Navigate</button>
);

const mapStateToProps = null;
const mapDispatchToProps = {
push
};

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

在我们的商店中拥有 URI 的好处之一是我们不需要访问 props.router 来更改位置,这打开了将登录逻辑移出我们的途径成分。有几种方法可以做到这一点,最简单的可能是 redux-thunk ,它允许我们的 Action 创建者返回函数而不是对象。然后我们可以编写我们的组件来简单地调用 login 函数并输入用户名和密码,我们的 thunk 会处理剩下的事情:

import { push } from 'react-router-redux';

// action creators....
const loginStarted = () => ({
type: 'LOGIN_STARTED'
)};

const loginFailed = (error) => ({
type: 'LOGIN_FAILED',
payload: {
error
}
};

const loginSucceeded = (user) => ({
type: 'LOGIN_SUCCEEDED',
payload: {
user
}
};

const getUserData = (access_token) => (dispatch) => {
Api.getUserData(access_token) // however you get user data
.then(response => {
dispatch(loginSucceeded(response.user));
dispatch(push(`/student/${response.user.username}`));
});

export const login = (username, password) => (dispatch) => {
dispatch(loginStarted());

Api.login({ username, password }) // however you call your backend
.then(response => {
if (response.success && response.access_token) {
getUserData(access_token)(dispatch);
} else {
dispatch(loginFailed(response.error));
}
});
}

你的组件唯一要做的就是调用初始登录函数,它可以像这样实现:

容器:

import React from 'react';
import { connect } from 'react-redux';

import { login } from '../path/to/actionCreators';
import LoginForm from './LoginForm';

const LoginContainer = React.createClass({
handleSubmit() {
this.props.login(
this.usernameInput.value,
this.passwordInput.value
);
},

setUsernameRef(input) {
this.usernameInput = input;
},

setPasswordRef(input) {
this.passwordInput = input;
},

render() {
return (
<LoginForm
handleSubmit={this.handleSubmit.bind(this)}
setUsernameRef={this.setUsernameRef.bind(this)}
setPasswordRef={this.setPasswordRef.bind(this)}
/>
);
}
});

const mapStateToProps = null;
const mapDispatchToProps = {
login
};

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

组件:

import React from 'react';

export const LoginForm = ({ handleSubmit, setUsernameRef, setPasswordRef }) => (
<div className="loginWrapper">
<div className="loginBox">
<form className="loginForm" action="">
<input ref={setUsernameRef} type="text" placeholder="username" defaultValue="kitties@kit.com" />
<input ref={setPasswordRef} type="text" placeholder="password" defaultValue="meowMeow3" />
<button onClick={handleSubmit}>Login</button>
</form>
</div>
</div>
);

这实现了逻辑/数据提供容器和无状态表示组件的分离。 LoginForm 组件可以简单地写成上面的函数,因为它不负责处理逻辑。容器也是一个非常简单的组件 - 逻辑已全部隔离在我们的 Action 创建者/thunk 中,并且更容易阅读和推理。

redux-thunk 只是使用 redux 管理异步副作用的一种方法 - 还有许多其他方法采用不同的方法。我个人的偏好是 redux-saga ,您可能会感兴趣。然而,在我自己的 redux 之旅中,我确实从使用和理解 redux-thunk 中受益,然后才发现它的局限性/缺点并继续前进,并且会向其他人推荐这条路线。

关于javascript - 根据 Redux 所做的状态变化来 react 事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42637416/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com