【发布时间】:2020-05-26 14:02:53
【问题描述】:
我正在构建一个响应式单页应用程序,它将根据用户的输入调用 API 进行搜索,并且用户必须登录才能使用该应用程序。
组件的层次结构是:
-
App.js(处理登录和路由) -
<SearchPage />和<SearchResults /> -
<SearchPage />下有<SearchNavBar />和<SearchMain />(<SearchMain />包含用户提交的表单和输入,提交后用户应该导航到<SearchResults />所在的路径。)
这里是问题:
由于 react 只允许一个方向的数据流,所以我必须将用户的输入从<SearchMain /> 向上传递给App.js,然后将其保存为App.js 的状态,并将其作为道具传递给<SearchResults />令牌来自App.js。但是,即使我已经更新了 App.js 中的状态,并将其作为 props 传递给其子组件<SearchResults />,而 console.logging 子组件 <SearchResults /> 的 props,我也只能得到初始值状态,而不是更新的,为什么??
代码:
App.js:
const myMSALObj = new UserAgentApplication(msalConfig);
class App extends Component {
constructor(props) {
super(props)
this.state = {
res:'',
isLoggedIn:false,
keyword:''
}
this.handleLogOut = this.handleLogOut.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleLogOut(){
myMSALObj.logout();
this.setState({isLoggedIn:false})
}
handleSubmit (typedValue){
this.setState({keyword:typedValue},() => console.log(this.state));//here works just fine, showing correct state value
window.location.replace('/results')
};
async componentDidMount(){
const idToken_response = await myMSALObj.loginPopup(loginRequest);
const response = await myMSALObj.acquireTokenPopup(loginRequest);
this.setState({isLoggedIn:true,res:response});
}
render(){
return (
<Router>
<div>
<Switch>
{this.state.isLoggedIn === true ?
<Route exact path="/" render={() => <SearchPage
parentState = {this.state}
handleLogOut = {this.handleLogOut}
handleSubmit = {this.handleSubmit} />}/>:
<Route exact path="/" render={() => (<div>Please wait till you are logged in...</div>)}/>}
<Route exact path="/results" render={() => <SearchResults
parentState = {this.state.keyword}
handleLogOut = {this.handleLogOut} />}/>
</Switch>
</div>
</Router>
);
}
}
export default App;
搜索页面:
class SeachPage extends Component{
constructor (props){
super (props);
this.state = {
// userInfo: this.props,
accessToken: this.props.parentState.res.accessToken,
name:this.props.parentState.res.account.name,
email:this.props.parentState.res.account.userName
}
// console.log(this.props)
}
render(){
return (
<Fragment>
<SearchNavBar
info={this.state}
handleLogOut = {this.props.handleLogOut}/>
<SearchMain
accessToken={this.state.accessToken }
handleSubmit = {this.props.handleSubmit}/>
</Fragment>
)
}
}
export default SeachPage;
搜索主要:
class SearchMain extends Component{
constructor(props){
super(props);
this.state = {
token:this.props.accessToken,
keyword:'',
typed:'',
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmitForm = this.handleSubmitForm.bind(this);
// console.log(this.props)
}
handleChange(event) {
let typed = event.target.value;
let keyword = event.target.value;
this.setState({typed: typed,keyword:keyword},() => console.log(this.state));
};
handleSubmitForm(event){
const keyword = this.state.keyword;
this.props.handleSubmit(keyword);
event.preventDefault();
}
render(){
return(
<div className="container" id="searchBox">
<form onSubmit = {this.handleSubmitForm } className="field is-grouped">
<p className="control is-expanded">
<input type="text" className="input" value={this.state.keyword} onChange={this.handleChange} autoComplete="off" placeholder="Find an asset" required></input>
</p>
<p className="control">
<button id="button-in-nav-bar" type="submit" className="button is-primary"><strong>Search</strong></button>
</p>
</form>
</div>
)
}
};
export default SearchMain;
搜索结果
class SearchResults extends Component {
constructor(props){
super(props);
console.log(this.props) //here is the issue!! onlyshowing{res:'',isLoggedIn:false,keyword:''}
}
render (){
return(
<div>test results</div>
)
}
};
export default SearchResults;
更新
简而言之,我能够将关键字向上传递给父组件,只是似乎有点晚了,截图可能更好地描述了我的挣扎:
如果我在第一个截图中取消注释window.location.replace('/results'),页面将导航到'/results',如果我在渲染函数中console.log(this.props),道具显示4次,最后2次有部分正确的信息。@ 987654324@,仍然缺少关键字...我有一种感觉,这可能是异步性质的,但我真的对如何修复它一无所知..(附带问题,为什么它是desiplayed 4次?)
【问题讨论】:
标签: javascript reactjs asynchronous async-await react-router