ReactJS组件不会重新呈现

时间:2018-03-22 18:59:43

标签: javascript reactjs react-router

我有一个以下示例简单页面:

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仍然显示我以前的文本(不是重新呈现)。

这个简单的页面有什么问题?

2 个答案:

答案 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
}

Here's a working demo.