0

这个问题是对此的后续:

React Router v4 和 MatchWithFade 的问题

我有另一个(可能很愚蠢)关于使用MatchWithFade和 React Router v4 的问题。我想做的是嵌套路由,所以顶级组件可能有这个:

<MatchWithFade pattern='/one' component={One} />

...然后One可能有这个:

<Match pattern='/one/one' Component={OneOne} />

这并没有让我觉得这是一个不寻常的模式(尽管也许是这样)。无论如何,我观察到的行为是,使用上面的示例,如果我 load OneOne,它会被挂载,然后componentWillUnmount立即被调用。如果我猜的话,我会说这TransitionMotion是跟踪一个(可能是隐藏的)实例OneOne,一旦转换完成,它就会卸载隐藏的组件。就基本 UI 而言,OneOne是呈现的。但是,如果componentWillUnmount进行任何清理(例如,从 Redux 中删除某些内容),那么该操作当然会被触发,并且与之相关的任何数据OneOne都会被吹走。

这是一个说明问题的完整示例:

import React, { Component } from 'react';
import BrowserRouter from 'react-router/BrowserRouter'

import { TransitionMotion, spring } from 'react-motion'
import Match from 'react-router/Match'
import Link from 'react-router/Link';

const styles = {
  fill: { position: 'absolute', top: 0, left: 0 }
};

const MatchWithFade = ({ component:Component, ...rest }) => {
  const willLeave = () => ({ zIndex: 1, opacity: spring(0) })

  return (
    <Match {...rest} children={({ matched, ...props }) => {
      return (
        <TransitionMotion
          willLeave={willLeave}
          styles={matched ? [ {
            key: props.location.pathname,
            style: { opacity: 1 },
            data: props
          } ] : []}
        >
          {interpolatedStyles => {
            return (
              <div>
                {interpolatedStyles.map(config => (
                  <div
                    key={config.key}
                    style={{...styles.fill, ...config.style }}>
                    <Component {...config.data}/>
                  </div>
                ))}
              </div>
            )
          }}
        </TransitionMotion>
      )
    }}/>
  )
}

const TwoOne = () => {
  return (
    <div>Two One</div>
  )
}


class TwoTwo extends Component {
  componentWillUnmount() {
    console.log("TwoTwo will unmount")
  }

  render () {
    return (
      <div>Two Two</div>
    )
  }
}


const TwoHome = () => {
  return (
    <div>Two Home</div>
  )
}


class One extends Component {
  componentWillUnmount () {
    console.log("ONE UNMOUNTING")
  }
  render () {
    return (
      <div style={{ width: 300, border: '1px solid black', backgroundColor: 'orange', minHeight: 200}}>
        One one one one one one one one one one<br />
        One one one one one one one one one one<br />
      </div>
    )
  }
}

const Two = () => {
  return (
    <div style={{ width: 300, border: '1px solid black', backgroundColor: 'yellow', minHeight: 200}}>
      <Match pattern='/two/one' component={TwoOne} />
      <Match pattern='/two/two' component={TwoTwo} />
      <Match pattern='/two(/)?' exactly={true} component={TwoHome} />
    </div>
  )
}


class App extends Component {

  render () {
    return (
        <BrowserRouter>
          <div style={{padding: 12}}>
            <div style={{marginBottom: 12}}>
              <Link to='/one'>One</Link> || <Link to='/two'>Two</Link>
              || <Link to='/two/one'>Two One</Link>
              || <Link to='/two/two'>Two Two</Link>
            </div>
            <div style={{position: 'relative'}}>
              <MatchWithFade pattern='/one' component={One} />
              <MatchWithFade pattern='/two' component={Two} />
            </div>
          </div>
        </BrowserRouter>
    )
  }
}

export default App;

One如果您加载它并打开控制台,请在和Two链接之间切换。您将在 UI 中看到交叉淡入淡出,当从一到二的转换完成时,您将在控制台中看到“ONE UNMOUNTING”。所以这是对的。

现在,单击Two One和之间Two Two。在这种情况下,Two One单击 时,您会立即在控制台中看到“TwoTwo will unmount”,这很好。但是,如果单击Two Two,您将在大约一秒钟后看到“TwoTwo 将卸载”——我认为这是父级MatchWithFade执行所花费的时间。

所以我不确定这里发生了什么。我的代码刚刚被破坏了吗?我在做 RRv4 无法支持的事情吗?我发现了一个错误吗?

任何帮助/指导表示赞赏!

4

1 回答 1

1

您的问题是您将其props.location.pathname用作密钥。对于组件,这应该始终相同,但是您编写它的方式,每次导航时都会改变。尝试改变这个:

const styles = {
  fill: { position: 'absolute', top: 0, left: 0 }
};

至:

const styles = {
  fill: { position: 'relative', top: 0, left: 0 }
};

你会看到你正在渲染两个实例<Two>(每个键一个)。

如果您要使用常量key,例如rest.pattern(与 this 关联的模式<Match>),您的问题就会消失。

styles={matched ? [ {
  key: rest.pattern,
  style: { opacity: 1 },
  data: props
} ] : []}
于 2017-01-16T22:39:41.883 回答