使用 React 和 Redux 的边栏过渡?
Sidebar transition with React and Redux?
所以我有一个 SideDrawer,我在根 App 组件中像这样渲染:
render() {
const { isOpen } = this.props;
return (
<BrowserRouter>
<SideDrawer />
{/* isOpen && <SideDrawer /> */}
<Routes ..../>
</BrowserRouter>
);
}
}
这是减速器:
export const drawer = (state = initialState, { type, payload }) => {
switch (type) {
case CLOSE_DRAWER:
return { ...state, isOpen: false };
case OPEN_DRAWER:
return { isOpen: true, movieId: payload };
default:
return state;
}
};
并且在 SideDrawer
组件中,我使用抽屉的状态和 css 来处理转换:
export const SideDrawer = ({ isOpen, closeDrawer, movieId }) => {
const drawerClass = cx({
container: true,
open: isOpen,
});
return (
<div className={drawerClass}>
<button className={styles.button} onClick={closeDrawer}>
<img src={backButton} alt={text.alt} />
</button>
<MovieBanner movieId={movieId} />
</div>
);
};
现在,我的导师要我有条件地渲染 SideDrawer。如果 isOpen
为真,则渲染 SideDrawer。但是,问题是过渡不会起作用,因为我只会在 isOpen
的状态为真时渲染 SideDrawer
。它现在工作的唯一方法是,如果我一直在 App
组件上渲染它,这样我就可以跟踪状态并在状态从 false
更改时添加我的 CSS 转换至 true
我的导师提到只有在 SideDrawer 打开时才渲染 SideDrawer,但我需要渲染它才能知道它以前的状态不是吗?
当元素从 DOM 中删除后,它将不再显示给用户。这也意味着 transition
s 对它没有影响。
如果您想使用过渡,请将元素保留在 DOM 中至少直到过渡完成,或一直保留。这是两个<div>
的演示,第一个总是在DOM,第二个只在sidebarOn
是true
时:
function Demo() {
const [sidebarOn, setSidebarOn] = React.useState(false)
const toggleSidebar = () => setSidebarOn(!sidebarOn)
return (
<div>
<button onClick={toggleSidebar}>toggle</button>
<div className={'sidebar ' + sidebarOn}>always rendered</div>
{sidebarOn &&
<div className={'sidebar ' + sidebarOn}>only rendered when on</div>
}
</div>
)
}
ReactDOM.render(<Demo />, document.getElementById('root'))
.sidebar {
background-color: yellow;
opacity: 0;
transition-property: opacity;
transition-duration: 500ms;
}
.sidebar.true {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>
存在一个 transitionend
event,您 可以 使用它在过渡结束后删除元素,但支持目前在浏览器中还不够普遍。
所以我有一个 SideDrawer,我在根 App 组件中像这样渲染:
render() {
const { isOpen } = this.props;
return (
<BrowserRouter>
<SideDrawer />
{/* isOpen && <SideDrawer /> */}
<Routes ..../>
</BrowserRouter>
);
}
}
这是减速器:
export const drawer = (state = initialState, { type, payload }) => {
switch (type) {
case CLOSE_DRAWER:
return { ...state, isOpen: false };
case OPEN_DRAWER:
return { isOpen: true, movieId: payload };
default:
return state;
}
};
并且在 SideDrawer
组件中,我使用抽屉的状态和 css 来处理转换:
export const SideDrawer = ({ isOpen, closeDrawer, movieId }) => {
const drawerClass = cx({
container: true,
open: isOpen,
});
return (
<div className={drawerClass}>
<button className={styles.button} onClick={closeDrawer}>
<img src={backButton} alt={text.alt} />
</button>
<MovieBanner movieId={movieId} />
</div>
);
};
现在,我的导师要我有条件地渲染 SideDrawer。如果 isOpen
为真,则渲染 SideDrawer。但是,问题是过渡不会起作用,因为我只会在 isOpen
的状态为真时渲染 SideDrawer
。它现在工作的唯一方法是,如果我一直在 App
组件上渲染它,这样我就可以跟踪状态并在状态从 false
更改时添加我的 CSS 转换至 true
我的导师提到只有在 SideDrawer 打开时才渲染 SideDrawer,但我需要渲染它才能知道它以前的状态不是吗?
当元素从 DOM 中删除后,它将不再显示给用户。这也意味着 transition
s 对它没有影响。
如果您想使用过渡,请将元素保留在 DOM 中至少直到过渡完成,或一直保留。这是两个<div>
的演示,第一个总是在DOM,第二个只在sidebarOn
是true
时:
function Demo() {
const [sidebarOn, setSidebarOn] = React.useState(false)
const toggleSidebar = () => setSidebarOn(!sidebarOn)
return (
<div>
<button onClick={toggleSidebar}>toggle</button>
<div className={'sidebar ' + sidebarOn}>always rendered</div>
{sidebarOn &&
<div className={'sidebar ' + sidebarOn}>only rendered when on</div>
}
</div>
)
}
ReactDOM.render(<Demo />, document.getElementById('root'))
.sidebar {
background-color: yellow;
opacity: 0;
transition-property: opacity;
transition-duration: 500ms;
}
.sidebar.true {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>
存在一个 transitionend
event,您 可以 使用它在过渡结束后删除元素,但支持目前在浏览器中还不够普遍。