下午好做出改变状态的事件监听器,阵营基于与终极版
我有一些困难反应,终极版时,我试图重定向基于状态的改变我的应用程序的用户的工作。
在高层次:我希望我的应用程序的路线改变,当我的user
对象处于状态填充了家庭信息/
到/student/:username
的信息。
现在我已经完成了这种在一种哈克式的时尚。
在我的Login
组件中,我使用componentDidUpdate
生命周期钩子来侦听和分派来自第三方API的访问令牌从我的Express服务器传回给客户端时的操作。
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>
)
}
});
请注意,我传递router
和user
我LoginForm
组件。我这样做是为了使用另一个componentDidUpdate
这里我用的是.push
方法上router
像这样:
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="[email protected]" />
<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
?
与往常一样,我会欣赏一些更有经验的眼睛在我的问题上,并期待一些反馈!
感谢
UPDATE
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;
这部分“洒”我的终极版的东西和状态数据到我命名StoreShell
容器组件,反过来所有的数据传递给构成UI的元素的道具类似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;
真的,我刚刚开始采用REDX,我很欣赏你的回复,因为我认为我理解REDX的目的更好一些。我喜欢URI作为国家的一部分,我认为这是一个聪明的做法。我有在这个项目中使用'redux-thunk'的经验,现在将扩展我的使用范围。这里有很多很棒的东西,我感谢你的全面回应。一个问题:为什么在'Login'组件的底部使用'connect'以及'mapStateToProps'和'mapDispatchToProps'?我在另一个“登录”上方的容器组件中执行此操作。我会更新我的问题向你展示。 – m00saca
我连接LoginContainer,因为对我来说这是最好的地方。虽然可以将登录actioncreator作为一个道具从高于树的连接组件传递,但这只会增加我不必要的复杂性。它也损害了组件的可重用性。即当LoginContainer连接时。如果你想在你的网站的其他地方放置另一个登录组件,那么你所需要做的就是导入它并渲染它。如果父组件负责“连接”,那么每次你想重新使用它时,你都必须连接它的父节点。 –
这对我来说很合理,因为我的组件被许多道具和调度程序污染了,例如'Login',这是我的'LoginForm'的容器就是这样。基于这个讨论,似乎我可以摆脱我上面的App.js组件,不是吗? – m00saca