我有一个以下示例简单页面:
App.js :
export default class App extends React.Component {
render() {
return <Router>
<Switch>
<Route exact path='/' component={ArticlesPage}/>
<Route path='/search' component={SearchPage}/>
</Switch>
</Router>
};
};
ArticlesPage.js :
export default class ArticlesPage extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Grid>
<Row>
<Col lg={12}>
<SearchBox/>
</Col>
</Row>
<Row>
<Col lg={12}>
articles
</Col>
</Row>
</Grid>;
}
};
SearchPage.js :
export default class SearchPage extends React.Component {
constructor(props) {
super(props);
const {q} = queryString.parse(location.search);
this.state = {
query: q
};
}
render() {
return <Grid>
<Row>
<Col lg={12}>
<SearchBox/>
</Col>
</Row>
<Row>
<Col lg={12}>
search {this.state.query}
</Col>
</Row>
</Grid>;
}
};
SearchBox.js :
export default class SearchBox extends React.Component {
constructor(props) {
super(props);
this.state = {
q: ''
};
}
onFormSubmit = (e) => {
e.preventDefault();
const {router} = this.context;
router.history.push('/search?q=' + this.state.q);
};
handleChange = (e) => {
this.setState({q: e.target.value});
};
render() {
return <form onSubmit={this.onFormSubmit}>
<Col lg={10} lgOffset={1}>
<FormGroup>
<input type="text" name="q" id="q" ref={i => this.searchInput = i} onChange={this.handleChange} />
</FormGroup>
</Col>
</form>;
}
};
现在,当我在索引页面上输入下一个发送表单中的内容时,React呈现SearchPage.js并正确返回文本search *and what I typed*
,再次尝试在输入中键入其他内容发送表单,React仍然显示我以前的文本(不是重新呈现)。
这个简单的页面有什么问题?
答案 0 :(得分:0)
您有两个不同的状态变量,query
上的<SearchPage />
和q
上的<SearchBox />
。您要更改的内容为q
,但您作为文字呈现的变量为query
。
您需要lift state up并将query
作为道具传递给<SearchPage />
。
答案 1 :(得分:0)
这就是为什么SearchPage
上的文本没有更新的原因:构造函数运行一次并更新状态中的变量,但是当应用程序重新渲染时,React,想要高效,看到它将在与前一个相同的位置重新渲染一个新的SearchPage
,因此它不会替换它,而是保持旧的状态。因此,SearchPage
的状态仍保留旧的q
变量。
以下是修复方法:让SearchPage
接受搜索查询作为道具,然后渲染。
class SearchPage extends React.Component {
render() {
return (
<Grid>
<Row>
<Col lg={12}>
<SearchBox />
</Col>
</Row>
<Row>
<Col lg={12}>search {this.props.query}</Col>
</Row>
</Grid>
)
}
}
在父级中,渲染它的路径,使用渲染函数,获取它的道具,解析来自props.location.search
的实际查询,并将其直接传递给SearchPage
。< / p>
<Route
path="/search"
render={props => <SearchPage query={getSearchQuery(props.location.search)} />}
/>
// utility function to keep things clean
function getSearchQuery(locationSearch) {
return queryString.parse(locationSearch.slice(1)).q
}