反应挂钩-更改路线时不会重置useState()中的状态

时间:2019-03-20 05:46:16

标签: javascript reactjs react-router-dom react-hooks

const Create = () => {
  console.log('rerender !!')
  const [parcelType, setParcelType] = useState('paper')
  console.log('parcelType =', parcelType)

  return (
    <Container onClick={() => setParcelType('plastic')}>
      <BookingList />
      <Card title="Business">
        <p>Header</p>
      </Card>
    </Container>
  )
}

export default Create

在“创建”组件中单击“容器”时,我想将parcelType状态更改为“可塑”。我想在更改路线时将parcelType状态重置为“纸”(创建组件重新渲染)。但是当组件的重新渲染状态未设置为纸张时

有关更多详细信息:在BookingList组件中更改路线时,将重新渲染CreateComponent

 const BookingList = props => {
  const { id } = props.match.params
  const containerStyle = useTranslateSpring('-100px', '0')

  const itemList = items.map((item, idx) => {
    const itemStyle = useTranslateSpring('-100px', '0', '0', 200 + 200 * idx)
    const url = `/booking/${item.id}/create`

    return (
      <ItemContainer
        onClick={() => props.history.push(url)}
        style={itemStyle}
        key={item.id}
        isactive={id === item.id}
      >
        {item.id}
      </ItemContainer>
    )
  })
  return <Container style={containerStyle}>{itemList}</Container>
}

export default withRouter(BookingList)

创建组件是通过routeTemplate在路由中呈现的

const Routes = () => (
 <Router basename={process.env.REACT_APP_BASE_URL}>
   <> 
    <RouteTemplate
    exact
    path="/booking/:id/create"
    component={Booking.create}
    title="Booking"
    />
   </>
 </Router>
)

而RouteTemplate是由PageTemplate组件包装的呈现组件

  const RouteTemplate = props => {
  const {
    component: Component,
    title,
    query,
    isAuthenticated,
    isLanding,
    ...rest
  } = props

  return (
    <Route
      {...rest}
      render={matchProps =>
        isAuthenticated ? (
          <PageTemplate title={title} isLanding={isLanding}>
            <Component {...matchProps} query={query} />
          </PageTemplate>
        ) : (
          <Redirect
            to={{
              pathname: '/',
              state: { from: props.location },
            }}
          />
        )
      }
    />
  )
}

1 个答案:

答案 0 :(得分:3)

因此,我假设您要在更改路线后重置组件的状态。

无论您在使用功能组件+挂钩或带有显式this.state的基于类的组件时,都应该发生这种情况。这就是React在后台运行的方式。

  1. 您已经在页面上渲染了<Create>
  2. 更改路线<Route>会尝试渲染<Create>元素
  3. React看到已经存在<Create>元素,并尝试对其进行更新而不是重新创建(通常,更新比重新创建要有效得多)。这就是为什么不重置状态-因为不应为更新而重置状态。

有不同的处理方式。

如果这种情况发生在React-Router的<Route>之外,我建议use key道具重置状态。但是对于<Route>,这意味着要用更详细的<Route path="..." component={Create} />

替换更清晰/简单的<Route path="..." render={({match}) => <Create match={match} key={match.params.id} />}

因此,让我们useEffect更改后,应用props.match.params.id钩子来重置状态:

const Create = ({ match: {params: {id} } }) => {    

  useEffect(() => {
    setParcelType('paper');
  }, [id]);

那应该等于基于类的

state = {
  typeOfWhatEver: 'paper'
};

componentDidUpdate(prevProps) {
  if(prevProps.match.params.id !== this.props.match.params.id) {
    this.setState({
      typeOfWhatEver: 'paper'
    });
  }
}