Как передать состояние родительскому компоненту при щелчке на ссылке "Реакция-маршрутизатор"?
Я хочу создать одностраничное приложение, которое работает с переходами, которое будет выглядеть следующим образом:
*------*--------------*-----------*
| | | |
| Shop | Landing Page | Biography |
| | | |
*------*--------------*-----------*
| |
| Contact page |
| |
*---------------------------------*
По сути, когда вы впервые заходите на сайт, вы попадаете на экран посадки. Оттуда доступны 3 ссылки: "Биография", "Магазин" и "Контакт" ("Контакт" доступен на трех "верхних" страницах).
После того, как вы щелкнете по ссылке, чтобы перейти в "Магазин" или "Биография", вы можете вернуться на посадку или перейти на страницу контактов, но вы не можете перейти на "противоположную" страницу (отсюда и схему). Кроме того, когда вы перейдете на страницу контактов и нажмете "назад", вы попадете на последнюю страницу, на которой вы были раньше.
Я создал CodeSandBox, чтобы избежать вставки полкилометра кода, который не обязательно имеет к этому какое-либо отношение, но все еще немного обеспокоен
Поэтому я хотел бы иметь возможность точно настроить свои переходы, например, переходя слева направо при переходе в "Биография" (и наоборот при выходе), справа налево при переходе в "Магазин" и снизу вверх при переходе в контактная форма.
После прочтения множества вопросов и документации о react-transition-group
У меня была идея сделать что-то вроде этого:
// src/App.js
const PageFade = props => (
// props.transition would contain "topBottom", "bottomTop", "leftRight" and "rightLeft"
// (so that I would ajust my CSS in consequence)
{props.transition === 'topBottom' &&
<CSSTransition
{...props}
classNames={props.transition !== null && props.transition}
timeout={1000}
mountOnEnter={true}
unmountOnExit={true}
/>
}
);
}
Я мог бы сделать это или создать <CSSTransition />
для каждой возможности я действительно не знаю.
Моя проблема в том, что мне нужно сказать это <CSSTransition />
или то, что было нажато, или (лучше), какой переход нужно отобразить.
Для этого я попытался установить transition
состояние, но похоже, что оно слишком сильно обновляется, и мои знания о React устарели, и я не знаю, как справиться со всем этим с помощью response-route.
Обновить
Спасибо всем за ваши ответы, и извините за то, что не отвечаете быстрее, мой компьютер замирает от безумия.
Итак, я создал новый класс CSSTransitions
где я скопировал / вставил ответ @ brandon, адаптируя его под свои нужды. Однако у меня есть проблема с componentWillReceiveProps(nextProps)
, поскольку он nextProps.location имеет значение null, каким-то образом контекст реагирующего маршрутизатора не передается.
Я обновил свой CodeSandBox, CSSTransitions
класс находится в каталоге 'utils' внутри каталога 'src'.
Еще раз спасибо за ваши ответы
заранее спасибо
2 ответа
Мое предложение состоит в том, чтобы ваш компонент PageFade отслеживал маршруты и сравнивал предыдущий маршрут с новым маршрутом и изменял его направление на основе изменения маршрутов. Вот грубый пример:
import {withRouter} from 'react-router';
const directions = {
"/->/contact": "top-bottom",
"/contact->/": "bottom-top",
// etc...
}
class PageFadeDumb extends React.Component {
state = {direction: "top-bottom"};
componentWillReceiveProps(nextProps) {
if (nextProps.location.pathname !== this.props.location.pathname) {
const transitionPath = `${this.props.location.pathname}->${nextProps.location.pathname}`;
const newDirection = directions[transitionPath] || "top-bottom";
console.log(`newDirection = ${newDirection}`);
this.setState({direction: newDirection});
}
}
render() {
const direction = this.state.direction;
// use here somehow?
return (
<CSSTransition
{...(this.props)}
classNames="fadeTranslate"
timeout={1000}
mountOnEnter={true}
unmountOnExit={true}
/>
);
}
}
const PageFade = withRouter(PageFadeDumb);
Я бы сделал это так:
class ParentComponent extends React.Component {
state = {
some_state: ""
}
myCallback = (ev) => {
this.setState({ some_state: ev.target.dataset.mydata });
}
render() {
<ChildComponent cback={this.myCallback} /> // Insert all other props too
}
}
class ChildComponent extends React.Component {
render() {
<button data-mydata="Value you need to pass up" onClick={this.props.cback}>
Click me
</button>
}
}
Когда кнопка нажата, обратный вызов, определенный в ParentComponent
запускается и получает объект Event, а затем вы можете захватить одно или несколько значений, используя атрибуты данных.
Чтобы узнать больше об этих data-
атрибуты и HTMLElement.dataset
Вы можете прочитать это.