我试图让一个组件出现在其他组件之间。为此,我想创建一个通用包装器,能够计算其子组件的大小并创建正确的动画。
到目前为止,当子元素的大小被硬编码时,我成功地(遇到了很多麻烦)以某种方式使组件按预期显示。但是一旦设置了填充或边距,它就不起作用了......
在这里查看我的测试用例:
import React from "react";
import ReactDOM from "react-dom";
import { View, Text, TouchableOpacity } from "react-native-web";
import styled from "styled-components";
const Container = styled(View)`
flex-direction: row;
`;
//The button that will make the component appear
class Toggle extends React.PureComponent {
render() {
return (
<TouchableOpacity {...this.props}>
<Text>Press Me</Text>
</TouchableOpacity>
);
}
}
//This wrapper will carry the appearing animation
const Wrapper = styled(View)`
transition: all ${props => props.delay}s ease;
transform: scale(${props => (props.mount ? 1 : 0)});
width: ${props => (props.mount ? props.width : 0)}px;
`;
//This is the component in charge of the appearing effect
class Appearing extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
mounted: false,
render: false,
width: 0
};
}
//This will start the animation
componentDidMount() {
this.setState({ mounted: true, render: true });
}
componentDidUpdate() {
//this will start the disappearing animation
if (this.state.mounted && !this.props.mount) {
this.setState({ mounted: false });
setTimeout(
() => this.setState({ render: false }),
this.props.delay * 1000
);
//this will restart the appearing animation
} else if (!this.state.mounted && this.props.mount) {
this.setState({ mounted: true, render: true });
}
//We read the expected this of the child component
this.setState({ width: this.getWidth ? this.getWidth() : 0 });
}
render() {
return (
<Wrapper {...this.props} width={this.state.width}>
{React.cloneElement(this.props.children, {
//We read the child size with the 'onLayout' method
onLayout: event =>
(this.getWidth = () => event.nativeEvent.layout.width)
})}
</Wrapper>
);
}
}
//Carry the test case
class App extends React.PureComponent {
state = { toggle: false };
render() {
return (
<View>
{/* with only the width set */}
<Container>
<Appearing delay={0.5} mount={this.state.toggle}>
<Text style={{ width: "9em" }}>Tadaaaaaaaa !</Text>
</Appearing>
<Toggle
onPress={() => this.setState({ toggle: !this.state.toggle })}
/>
</Container>
{/* with the width and padding set */}
<Container>
<Appearing delay={0.5} mount={this.state.toggle}>
<Text style={{ width: "9em", paddingLeft: "10em" }}>
Tadaaaaaaaa !
</Text>
</Appearing>
<Toggle
onPress={() => this.setState({ toggle: !this.state.toggle })}
/>
</Container>
</View>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
您知道实现这一目标的最佳方法吗?