下午好做出改變狀態的事件監聽器,陣營基於與終極版
我有一些困難反應,終極版時,我試圖重定向基於狀態的改變我的應用程序的用戶的工作。
在高層次:我希望我的應用程序的路線改變,當我的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