React hooks - состояние в useState () не сбрасывается при изменении маршрута - PullRequest
1 голос
/ 20 марта 2019
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 на «бумажный» при изменении маршрута (Создать повторный рендеринг компонента).Но когда для состояния повторного рендеринга компонента не задано значение paper

. Для получения более подробной информации: CreateComponent повторно рендерит при изменении маршрута в компоненте BookingList

 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 Ответ

4 голосов
/ 20 марта 2019

Итак, я предполагаю, что вы хотите сбросить состояние компонента после изменения маршрута.

Это должно происходить везде, где вы используете функциональный компонент + хуки или компонент на основе классов с явным this.state. Так работает React под капотом.

  1. У вас уже есть <Create> на странице
  2. После изменения маршрута <Route> пытается отобразить <Create> element
  3. React видит, что уже существует элемент <Create> , и пытается обновить его вместо повторного создания (обычно обновление гораздо эффективнее, чем повторное создание). Вот почему состояние не сбрасывается - поскольку оно не должно сбрасываться для обновлений.

Есть другой способ справиться с этим.

Если такой случай произойдет вне <Route> маршрутизатора реакции, я бы предложил использовать key prop для сброса состояния. Но для <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'
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...