React Router组件无法重新渲染

时间:2018-03-28 00:47:20

标签: reactjs react-router

我有以下代码。

const RoutedApp = () => {
  return (
    <BrowserRouter>
      <HeaderAndDrawer>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/question/:id" component={QuestionPage} />
          <Route component={PageNotFound} />
        </Switch>
      </HeaderAndDrawer>
    </BrowserRouter>
  );
};

HeaderAndDrawer中有一个按钮,点击后会更改网址以指向新问题(例如/question/10QuestionPage应更新以显示相应的新问题问题(问题10)。

目前,当URL更改时,QuestionPage组件不会重新呈现。我没有使用Redux,所以connect不是问题。

我可以在这里尝试什么?

Code Sandbox

https://codesandbox.io/s/z35q45xyr3

截屏

enter image description here

正如您所看到的,从PageNotFound切换到QuestionPage时一切正常,但在QuestionPage上时,新网址不会更新页面。

相关代码

HeaderAndDrawer.js

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { withStyles } from 'material-ui/styles';
import QuestionDrawer from './QuestionDrawer';

// some imports here, left out for brevity
// some styling here, left out for brevity 

const HeaderAndDrawer = props => {
  const { classes } = props;

  return (
    <div className={classes.root}>
      <AppBar position="absolute" className={classes.appBar}>
        <Toolbar>
          <Typography variant="title" color="inherit" noWrap>
            app bar title
          </Typography>
        </Toolbar>
      </AppBar>
      <QuestionDrawer />
      <main className={classes.content}>
        <div className={classes.toolbar} />
        {props.children}
      </main>
    </div>
  );
};

export default withStyles(styles)(HeaderAndDrawer);

QuestionDrawer.js

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { withStyles } from 'material-ui/styles';
import { withRouter } from 'react-router-dom';

// some imports here, left out for brevity
// some styling here, left out for brevity

class QuestionDrawer extends Component {
  state = {
    questionIds: [],
    loading: true,
  };

  async componentWillMount() {
    const questionIds = await getDrawerQuestionIds();

    this.setState({
      questionIds,
      loading: false,
    });
  }

  renderDrawerList() {
    const { questionIds } = this.state;

    return (
      <List>
        <div>
          {questionIds.map(qid => {
            return (
              <ListItem
                button
                key={qid}
                onClick={() => {
                  this.props.history.push(`/question/${qid}`);
                }}
              >
                <ListItemIcon>
                  <CodeIcon />
                </ListItemIcon>
                <ListItemText primary={qid} />
              </ListItem>
            );
          })}
        </div>
      </List>
    );
  }

  render() {
    if (this.state.loading) {
      return null;
    }

    const { classes } = this.props;

    return (
      <Drawer
        variant="permanent"
        classes={{
          paper: classes.drawerPaper,
        }}
      >
        <div className={classes.toolbar} />
        {this.renderDrawerList()}
      </Drawer>
    );
  }
}

export default withRouter(withStyles(styles)(QuestionDrawer));

QuestionPage.js

import React, { Component } from 'react';
import { View, Text } from 'react-native';

// some imports here, left out for brevity

// some styles here, left out for brevity 

class QuestionPage extends Component {
  state = {
    question: null,
    loading: true,
  };

  async componentWillMount() {
    const { id } = this.props.match.params;
    const question = await getQuestion(id);

    this.setState({
      question,
      loading: false,
    });
  }

  renderError() {
    const title = 'Question does not exist.';
    const text = 'Please check the id.';

    return (
      <View style={styles.questionCardContainer}>
        <QuestionCard title={title} text={text} />
      </View>
    );
  }

  render() {
    if (this.state.loading) {
      return (
        <View style={styles.loadingContainer}>
          <CircularProgress size={50} />
        </View>
      );
    }

    let title, text;

    if (this.state.question) {
      title = this.state.question.title;
      text = this.state.question.text;
    } else {
      return this.renderError();
    }

    return (
      <View>
        <View style={styles.questionCardContainer}>
          <QuestionCard title={title} text={text} />
        </View>
      </View>
    );
  }
}

export default QuestionPage;

1 个答案:

答案 0 :(得分:0)

要触发刷新,您必须更改QuestionPage的状态。您的代码示例不够全面,或者您只是没有在QuestionPage构造函数中添加处理。 例如,

class QuestionPage extends React.Component {
    super(props);
    this.state = {
        questionId: this.props.match.params.id
    }
}

您应该使用componentWillMount()函数向您的QuestionPage添加函数,以加载数据库中的相关问题。