单击 react-router Link 时如何将状态传输到父组件?
How do I transmit a state to a parent component when clicking a react-router Link?
我想构建一个使用转换的单页应用程序,如下所示:
*------*--------------*-----------*
| | | |
| Shop | Landing Page | Biography |
| | | |
*------*--------------*-----------*
| |
| Contact page |
| |
*---------------------------------*
基本上,当您第一次访问该网站时,您会到达登陆屏幕。从那里,有 3 个 link 可用,'Biography'、'Shop' 和 'Contact'('Contact' 可从三个 'top' 页面获得)。
一旦您点击 link 转到 'Shop' 或 'Biography',您可以返回登录页面或转到联系页面,但不能转到“对面”页面(因此是架构)。此外,当您进入联系页面并单击 'back' 时,您将进入之前的最后一页。
我创建了一个 CodeSandBox 以避免粘贴半公里的代码,这些代码不一定与此有任何关系但仍然有点担心
所以我希望能够精确地设置我的过渡,比如去 'Biography' 时从左到右(离开时相反),去“商店”时从右到左,进入联系表格时从下到上。
在阅读了大量关于 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的了解很生疏,我不知道如何处理这一切反应路线。
更新
谢谢大家的回答,很抱歉没有尽快回答,我的电脑快死机了。
所以我创建了一个新的 class CSSTransitions
,我在其中复制/粘贴了@brandon 的答案,同时根据我的需要对其进行了调整。
但是,我对 componentWillReceiveProps(nextProps)
有一个问题,因为它 nextProps.location 是空的,不知何故,react-router 的上下文没有被传递。
我更新了我的 CodeSandBox,CSSTransitions
class 在 'src' 目录中的 'utils' 目录中。
再次感谢您的回答
提前致谢
我会这样做:
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 object and then you may capture one or more values using data- attributes。
要了解有关这些 data-
属性和 HTMLElement.dataset
的更多信息,您可以阅读 this。
我的建议是只让您的 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);
我想构建一个使用转换的单页应用程序,如下所示:
*------*--------------*-----------*
| | | |
| Shop | Landing Page | Biography |
| | | |
*------*--------------*-----------*
| |
| Contact page |
| |
*---------------------------------*
基本上,当您第一次访问该网站时,您会到达登陆屏幕。从那里,有 3 个 link 可用,'Biography'、'Shop' 和 'Contact'('Contact' 可从三个 'top' 页面获得)。
一旦您点击 link 转到 'Shop' 或 'Biography',您可以返回登录页面或转到联系页面,但不能转到“对面”页面(因此是架构)。此外,当您进入联系页面并单击 'back' 时,您将进入之前的最后一页。
我创建了一个 CodeSandBox 以避免粘贴半公里的代码,这些代码不一定与此有任何关系但仍然有点担心
所以我希望能够精确地设置我的过渡,比如去 'Biography' 时从左到右(离开时相反),去“商店”时从右到左,进入联系表格时从下到上。
在阅读了大量关于 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的了解很生疏,我不知道如何处理这一切反应路线。
更新
谢谢大家的回答,很抱歉没有尽快回答,我的电脑快死机了。
所以我创建了一个新的 class CSSTransitions
,我在其中复制/粘贴了@brandon 的答案,同时根据我的需要对其进行了调整。
但是,我对 componentWillReceiveProps(nextProps)
有一个问题,因为它 nextProps.location 是空的,不知何故,react-router 的上下文没有被传递。
我更新了我的 CodeSandBox,CSSTransitions
class 在 'src' 目录中的 'utils' 目录中。
再次感谢您的回答
提前致谢
我会这样做:
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 object and then you may capture one or more values using data- attributes。
要了解有关这些 data-
属性和 HTMLElement.dataset
的更多信息,您可以阅读 this。
我的建议是只让您的 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);