- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在关注 Chang Wang 的使用 HOC 和 ReactTransitionGroup
进行可重用 React 转换的教程。 ( Part 1 Part 2 ) 与 Huan Ji 关于页面转换的教程 ( Link )。
我面临的问题是 React.cloneElement
似乎没有将更新的 Prop 传递给它的一个 child ,而其他 child 确实正确地接收更新的 Prop 。
首先,一些代码:
TransitionContainer.js TransitionContainer
是一个类似于 App
的容器组件在欢姬的教程中。它向它的 child 注入(inject)了状态的一部分。TransitionGroup
的 children 都是名为 Transition
的 HOC 的实例(代码进一步向下)
import React from 'react';
import TransitionGroup from 'react-addons-transition-group';
import {connect} from 'react-redux';
class TransitionContainer extends React.Component{
render(){
console.log(this.props.transitionState);
console.log("transitionContainer");
return(
<div>
<TransitionGroup>
{
React.Children.map(this.props.children,
(child) => React.cloneElement(child, //These children are all instances of the Transition HOC
{ key: child.props.route.path + "//" + child.type.displayName,
dispatch: this.props.dispatch,
transitionState: this.props.transitionState
}
)
)
}
</TransitionGroup>
</div>
)
}
}
export default connect((state)=>({transitionState:state.transitions}),(dispatch)=>({dispatch:dispatch}))(TransitionContainer)
Transition
类似于 Chang Wang 的 HOC。它需要一些选项,定义
componentWillEnter
+
componentWillLeave
钩子(Hook),并包装一个组件。
TransitionContainer
(上)注入(inject)
props.transitionState
进入这个 HOC。但是,有时即使状态发生变化, Prop 也不会更新(请参阅下面的
问题 )
import React from 'react';
import getDisplayName from 'react-display-name';
import merge from 'lodash/merge'
import classnames from 'classnames'
import * as actions from './actions/transitions'
export function transition(WrappedComponent, options) {
return class Transition extends React.Component {
static displayName = `Transition(${getDisplayName(WrappedComponent)})`;
constructor(props) {
super(props);
this.state = {
willLeave:false,
willEnter:false,
key: options.key
};
}
componentWillMount(){
this.props.dispatch(actions.registerComponent(this.state.key))
}
componentWillUnmount(){
this.props.dispatch(actions.destroyComponent(this.state.key))
}
resetState(){
this.setState(merge(this.state,{
willLeave: false,
willEnter: false
}));
}
doTransition(callback,optionSlice,willLeave,willEnter){
let {transitionState,dispatch} = this.props;
if(optionSlice.transitionBegin){
optionSlice.transitionBegin(transitionState,dispatch)
}
if(willLeave){
dispatch(actions.willLeave(this.state.key))
}
else if(willEnter){
dispatch(actions.willEnter(this.state.key))
}
this.setState(merge(this.state,{
willLeave: willLeave,
willEnter: willEnter
}));
setTimeout(()=>{
if(optionSlice.transitionComplete){
optionSlice.transitionEnd(transitionState,dispatch);
}
dispatch(actions.transitionComplete(this.state.key))
this.resetState();
callback();
},optionSlice.duration);
}
componentWillLeave(callback){
this.doTransition(callback,options.willLeave,true,false)
}
componentWillEnter(callback){
this.doTransition(callback,options.willEnter,false,true)
}
render() {
console.log(this.props.transitionState);
console.log(this.state.key);
var willEnterClasses = options.willEnter.classNames
var willLeaveClasses = options.willLeave.classNames
var classes = classnames(
{[willEnterClasses] : this.state.willEnter},
{[willLeaveClasses] : this.state.willLeave},
)
return <WrappedComponent animationClasses={classes} {...this.props}/>
}
}
}
{
willEnter:{
classNames : "a b c",
duration: 1000,
transitionBegin: (state,dispatch) => {//some custom logic.},
transitionEnd: (state,dispatch) => {//some custom logic.}
// I currently am not passing anything here, but I hope to make this a library
// and am adding the feature to cover any use case that may require it.
},
willLeave:{
classNames : "a b c",
duration: 1000,
transitionBegin: (state,dispatch) => {//some custom logic.},
transitionEnd: (state,dispatch) => {//some custom logic.}
}
}
actions.registerComponent
被 dispatch componentWillMount
componentWillLeave
或 componentWillEnter
钩子(Hook)被调用,相应的选项切片被发送到doTransition
optionSlice.transitionBegin
)action.willLeave
或 action.willEnter
已发货 optionSlice.duration
)。超时完成后:optionSlice.transitionEnd
)actions.transitionComplete
已发货 optionSlice.transitionBegin
和
optionSlice.transitionEnd
只是在动画进行时执行的可选函数,如果这适合用例的话。我目前没有为我的组件传递任何东西,但我希望很快将它变成一个库,所以我只是覆盖了我的基础。
TransitionGroup
包含两个元素,一个进入,一个退出(由 react-router 控制)。它传递了一个名为
transitionState
的 Prop 给它的 child 。
Transition
HOC(
TransitionGroup
的 child )在动画过程中分派(dispatch)某些 redux Action 。
Transition
正在进入的组件按预期接收 Prop 更改,但正在退出的组件被卡住。它的 Prop 不会改变。
import React from 'react';
import TransitionGroup from 'react-addons-transition-group';
import {connect} from 'react-redux';
var childFactoryMaker = (transitionState,dispatch) => (child) => {
console.log(child)
return React.cloneElement(child, {
key: (child.props.route.path + "//" + child.type.displayName),
transitionState: transitionState,
dispatch: dispatch
})
}
class TransitionContainer extends React.Component{
render(){
let{
transitionState,
dispatch,
children
} = this.props
return(
<div>
<TransitionGroup childFactory={childFactoryMaker(transitionState,dispatch)}>
{
children
}
</TransitionGroup>
</div>
)
}
}
export default connect((state)=>({transitionState:state.transitions}),(dispatch)=>({dispatch:dispatch}))(TransitionContainer)
TransitionContainer
以上。现在,
componentWillEnter
和
componentWillLeave
钩子(Hook)没有被调用。我登录了
React.cloneElement(child, {...})
在
childFactory
函数和钩子(Hook)(以及我定义的函数,如
doTransition
)存在于
prototype
中属性。只有
constructor
,
componentWillMount
和
componentWillUnmount
叫做。我怀疑这是因为
key
Prop 未通过
React.cloneElement
注入(inject).
transitionState
和
dispatch
虽然正在注入(inject)。
import React from 'react';
import TransitionGroup from 'react-addons-transition-group';
import {connect} from 'react-redux';
var childFactoryMaker = (transitionState,dispatch) => (child) => {
console.log(React.cloneElement(child, {
transitionState: transitionState,
dispatch: dispatch
}));
return React.cloneElement(child, {
key: (child.props.route.path + "//" + child.type.displayName),
transitionState: transitionState,
dispatch: dispatch
})
}
class TransitionContainer extends React.Component{
render(){
let{
transitionState,
dispatch,
children
} = this.props
return(
<div>
<TransitionGroup childFactory={childFactoryMaker(transitionState,dispatch)}>
{
React.Children.map(this.props.children,
(child) => React.cloneElement(child, //These children are all instances of the Transition HOC
{ key: child.props.route.path + "//" + child.type.displayName}
)
)
}
</TransitionGroup>
</div>
)
}
}
export default connect((state)=>({transitionState:state.transitions}),(dispatch)=>({dispatch:dispatch}))(TransitionContainer)
最佳答案
确定进入和离开 child
想象一下渲染下面的示例 JSX:
<TransitionGroup>
<div key="one">Foo</div>
<div key="two">Bar</div>
</TransitionGroup>
<TransitionGroup>
的
children
prop 将由以下元素组成:
[
{ type: 'div', props: { key: 'one', children: 'Foo' }},
{ type: 'div', props: { key: 'two', children: 'Bar' }}
]
state.children
.然后,我们更新
<TransitionGroup>
到:
<TransitionGroup>
<div key="two">Bar</div>
<div key="three">Baz</div>
</TransitionGroup>
componentWillReceiveProps
被称为,其
nextProps.children
将会:
[
{ type: 'div', props: { key: 'two', children: 'Bar' }},
{ type: 'div', props: { key: 'three', children: 'Baz' }}
]
state.children
和
nextProps.children
,我们可以确定:
{ type: 'div', props: { key: 'one', children: 'Foo' }}
正在离开
{ type: 'div', props: { key: 'three', children: 'Baz' }}
正在进入。
<div>Foo</div>
将不再被渲染,但对于
<TransitionGroup>
的 child 来说情况并非如此。 .
<TransitionGroup>
作品
<TransitionGroup>
究竟是怎样的?能够继续渲染
props.children
中不再存在的组件?
<TransitionGroup>
确实是它维护了一个
children
阵列处于其状态。每当
<TransitionGroup>
接收新 Prop ,此数组由
merging 更新当前
state.children
和
nextProps.children
. (初始数组是在
constructor
中使用初始
children
Prop 创建的)。
<TransitionGroup>
渲染,它渲染
state.children
中的每个 child 大批。渲染完成后,它会调用
performEnter
和
performLeave
任何进入或离开的 child 。这将依次执行组件的转换方法。
componentWillLeave
方法(如果有)已完成执行,它将自己从
state.children
中删除数组,以便它不再呈现(假设它在离开时没有重新进入)。
<TransitionGroup>
而被渲染。将其存储在其
state
中.
<TransitionGroup>
的 child 时通过
React.cloneElement
,离开组件不是这些 child 之一。
childFactory
支持您的
<TransitionGroup>
.默认
childFactory
只是返回 child ,但你可以看看
<CSSTransitionGroup>
更多
advanced child factory .
function childFactory(child) {
return React.cloneElement(child, {
transitionState,
dispatch
})
}
var ConnectedTransitionGroup = connect(
store => ({
transitionState: state.transitions
}),
dispatch => ({ dispatch })
)(TransitionGroup)
render() {
return (
<ConnectedTransitionGroup childFactory={childFactory}>
{children}
</ConnectedTransitionGroup>
)
}
关于reactjs - React TransitionGroup 和 React.cloneElement 不发送更新的 props,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41404232/
我正在尝试使用 React 和 Typescript 制作仪表板。我使用 Card 组件通过 React.cloneElement 将子组件推送到其中,并添加 Card 的 setStates 以从子
我想使用 {React.cloneElement(, { onClick: () => console.log('click'), style: {background: 'red'} })} 向我的
使用 React.cloneElement 会导致我似乎无法解决的类型错误。 class Dropdown extends React.Component> }> { render() {
如果我有的话,originalComponent 是否会被垃圾回收: const WrapperComponent = ({ originalComponent, ...props }) => {
我很难理解 React.cloneElement() 函数的行为 我的组件结构是这样的 A.js export default class A extends React.Component {
我正在尝试创建一个高阶组件 Hoc,它通过 React.cloneElement 为其子组件提供一些额外的 Prop 。我一直无法让 flowtype 知道额外的 Prop 实际上已经被传递了下来。
我想解决此库的问题:react-form 。有关信息,这是我当前的错误: Uncaught Error: Element type is invalid: expected a string (for
我正在使用 React 和 Typescript。我有一个充当包装器的 react 组件,我希望将它的属性复制到它的子组件。我正在遵循 React 的克隆元素使用指南:https://facebook
我正在构建一个动态生成键的表控件(我理解这可能不是一个好主意——我认为键应该与它所代表的数据唯一关联,否则 React 只能为我们生成唯一的 ID?),但无论哪种方式,似乎都没有设置 key ,我不知
我有同样的问题,我已经使用了 create-react-app我的 react-toastify 版本是 ^9.0.8。请帮我这是完整的消息:./node_modules/react-toastify
如何使用 React.cloneElement 附加或更改 className 属性? 当我使用 React.cloneElement 时,我无法更改或附加 className Prop 。我已经搜索
我有 TestWrapper克隆 element 的组件并且应该使背景变为蓝色。 Test也在做同样的事情,但设置 color .我期待渲染的元素有蓝色背景和红色文本,但它只是 red .这是示例:
我正在使用 React 组合一个表格控件,它几乎一直遵循这种模式一直到单元格: class Table extends Component { static propTypes = {
我不明白 React official docs 中所写陈述的意义: cloneElement() React.cloneElement( element, [props], [...ch
我一直在测试使用 React.cloneElement() 扩展组件的 children 可能存在的限制/危险。我发现的一种可能的危险是可能会覆盖 ref 和 key 等 Prop 。 但是,根据 R
任何人都可以告诉我使用 cloneElement(在现有元素实例上)还是 createElement(在 React Element 类上)哪个在性能方面更好? 有时克隆某些东西比创建新实例更快。请告
我想知道当您将 ES6 和 cloneElement 传递给函数时它是如何工作的。我需要在父组件的状态中引用状态,但 this 引用子组件而不是父组件。 下面是使它工作的常规 JavaScript 代
我正在学习 React 并试图找出动态添加 props 的最佳方法。我知道两种方法可以做到这一点,但不知道哪一种更好更快。 第一种方法是使用 React.cloneElement api const
假设我有一个具有 className 的 ReactElement,并且我想向其 className 添加一个新类,而不覆盖现有的 className。我该怎么做? 我尝试了以下方法,但它确实覆盖了现
React.cloneElement() 总是需要第一个参数作为 react 组件,它应该作为 Prop 中的 child 传递。 有没有办法将一个简单的 HTML 节点作为子节点传递。请引用下面的代
我是一名优秀的程序员,十分优秀!