由于前面有 return,因此无法看到条件渲染
Conditional rendering cannot be seen due to a return before them
请帮我起一个更好的标题,我不知道我在问什么。
要理解我的问题,我必须提供我项目的一些背景信息。本来想通过两个按钮有条件地渲染两个页面。按钮 A 呈现屏幕 A 和按钮 B 呈现屏幕 B。在弄清楚如何将状态从 parent 组件传递到 child 及其 child 等之后,我将按钮更改为滑动动画以获得更好的设计。
这会导致问题,因为现在渲染新屏幕时,动画不会显示,因为它只是 re-rendered 与动画中的原始起始位置(我在每个屏幕上都渲染了滑块)。我考虑过提供两个不同的滑块,每个滑块都从相反的方向开始,但仍然会失去整个滑块效果。
我现在已经 渲染了 Slider,所以它一直在那里,而不是 re-rendered。但是我现在已经意识到,如果我在我的条件语句之前 return 它,则永远不会到达该代码。我提供了一个可以完美显示我的问题的工作演示以及下面的代码(我只提供了 App.js,如果需要,其余的在演示中)。我想在 App.js.
中渲染 Slider
工作演示是here,你可以看到滑块没有滑动,它只是改变了屏幕。我需要它滑动。此外,滑动动画仅适用于 iphone,因此我会使用该模拟器而不是网络。
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
whichComponentToShow: "Screen1"
};
}
goToMap = () => {
this.setState({ whichComponentToShow: "Screen2" });
};
goToList = () => {
this.setState({ whichComponentToShow: "Screen1" });
};
render() {
const { whichComponentToShow } = this.state;
/* This is how I thought I could render this, but obv it makes the rest of the code unreachable.
How can I render this and then have the conditional page below? Each time the new page renders,
it stops the animation from working due to rendering the new page.
return(
<Slider/>
)*/
if(this.state.whichComponentToShow === 'Screen1'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<ListHome
renderMap = {this.goToMap.bind(this)}
renderList = {this.goToList.bind(this)}
/>
</View>
);
}
else if(this.state.whichComponentToShow === 'Screen2'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<MapHome
renderMap = {this.goToMap.bind(this)}
renderList = {this.goToList.bind(this)}
/>
</View>
);
}
Slider.js(不会出现在零食 apparently
const Slider = (props) => {
const [active, setActive] = useState(false)
let transformX = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (active) {
Animated.timing(transformX, {
toValue: 1,
duration: 300,
useNativeDriver: true
}).start()
} else {
Animated.timing(transformX, {
toValue: 0,
duration: 300,
useNativeDriver: true
}).start()
}
}, [active]);
const rotationX = transformX.interpolate({
inputRange: [0, 1],
outputRange: [2, Dimensions.get('screen').width / 4]
})
return (
<SafeAreaView style={{
flex: 1,
alignItems: 'center'
}}>
<View style={{
flexDirection: 'row',
position: 'relative',
height: 45,
width: 240,
borderRadius: 10,
backgroundColor: 'white',
marginHorizontal: 5
}}>
<Animated.View
style={{
position: 'absolute',
height: 45 - 2*2,
top: 2,
bottom: 2,
borderRadius: 10,
width: Dimensions
.get('screen').width / 3 - 3.5 ,
transform: [
{
translateX: rotationX
}
],
backgroundColor: '#d1cfcf',
}}
>
</Animated.View>
<TouchableOpacity style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}} onPress={() => {setActive(false); props.renderList() }}>
<Text>
List
</Text>
</TouchableOpacity>
<TouchableOpacity style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}} onPress={() => {setActive(true); props.renderMap() }}>
<Text>
Map
</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
export default Slider
我试过你的 expo
snack 并没有看到与动画相关的代码,所以我假设 snack 中的代码不是你当前的代码,你确实已经有了一个有效的动画, <Slider ... />
.
在您的情况下,要保持 Slider
呈现而不是卸载,您可以做的是在 render()
方法中使用变量。
基本上,您可以将 JSX 分配给一个变量,稍后您可以在另一个 JSX 部分中使用该变量。
将 key
分配给特定的 JSX 也有助于指导 React 在渲染调用之间这是相同的组件,因此它也可以防止该组件的无意重新渲染。
这是对您在 post 中所写内容的评论的编辑。我希望这是有道理的。
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
whichComponentToShow: "Screen1"
};
}
goToMap = () => {
this.setState({ whichComponentToShow: "Screen2" });
};
goToList = () => {
this.setState({ whichComponentToShow: "Screen1" });
};
render() {
const { whichComponentToShow } = this.state;
/*
Keep the slider JSX in a variable to be used.
Setting a specific key also helps prevent it from being accidentally re-rendered in some conditions.
)*/
const sliderRender = <Slider key='slider' />;
if (this.state.whichComponentToShow === 'Screen1') {
return (
<View style={{ backgroundColor: '#d1cfcf', flex: 1 }}>
<ListHome
renderMap={this.goToMap.bind(this)}
renderList={this.goToList.bind(this)}
/>
{/* Put the rendered slider into the render tree */}
{sliderRender}
</View>
);
}
else if (this.state.whichComponentToShow === 'Screen2') {
return (
<View style={{ backgroundColor: '#d1cfcf', flex: 1 }}>
<MapHome
renderMap={this.goToMap.bind(this)}
renderList={this.goToList.bind(this)}
/>
{/* Put the rendered slider into the render tree */}
{sliderRender}
</View>
);
}
}
}
编辑:Expo Snack 演示其工作
请帮我起一个更好的标题,我不知道我在问什么。
要理解我的问题,我必须提供我项目的一些背景信息。本来想通过两个按钮有条件地渲染两个页面。按钮 A 呈现屏幕 A 和按钮 B 呈现屏幕 B。在弄清楚如何将状态从 parent 组件传递到 child 及其 child 等之后,我将按钮更改为滑动动画以获得更好的设计。
这会导致问题,因为现在渲染新屏幕时,动画不会显示,因为它只是 re-rendered 与动画中的原始起始位置(我在每个屏幕上都渲染了滑块)。我考虑过提供两个不同的滑块,每个滑块都从相反的方向开始,但仍然会失去整个滑块效果。
我现在已经 渲染了 Slider,所以它一直在那里,而不是 re-rendered。但是我现在已经意识到,如果我在我的条件语句之前 return 它,则永远不会到达该代码。我提供了一个可以完美显示我的问题的工作演示以及下面的代码(我只提供了 App.js,如果需要,其余的在演示中)。我想在 App.js.
中渲染 Slider工作演示是here,你可以看到滑块没有滑动,它只是改变了屏幕。我需要它滑动。此外,滑动动画仅适用于 iphone,因此我会使用该模拟器而不是网络。
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
whichComponentToShow: "Screen1"
};
}
goToMap = () => {
this.setState({ whichComponentToShow: "Screen2" });
};
goToList = () => {
this.setState({ whichComponentToShow: "Screen1" });
};
render() {
const { whichComponentToShow } = this.state;
/* This is how I thought I could render this, but obv it makes the rest of the code unreachable.
How can I render this and then have the conditional page below? Each time the new page renders,
it stops the animation from working due to rendering the new page.
return(
<Slider/>
)*/
if(this.state.whichComponentToShow === 'Screen1'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<ListHome
renderMap = {this.goToMap.bind(this)}
renderList = {this.goToList.bind(this)}
/>
</View>
);
}
else if(this.state.whichComponentToShow === 'Screen2'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<MapHome
renderMap = {this.goToMap.bind(this)}
renderList = {this.goToList.bind(this)}
/>
</View>
);
}
Slider.js(不会出现在零食 apparently
const Slider = (props) => {
const [active, setActive] = useState(false)
let transformX = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (active) {
Animated.timing(transformX, {
toValue: 1,
duration: 300,
useNativeDriver: true
}).start()
} else {
Animated.timing(transformX, {
toValue: 0,
duration: 300,
useNativeDriver: true
}).start()
}
}, [active]);
const rotationX = transformX.interpolate({
inputRange: [0, 1],
outputRange: [2, Dimensions.get('screen').width / 4]
})
return (
<SafeAreaView style={{
flex: 1,
alignItems: 'center'
}}>
<View style={{
flexDirection: 'row',
position: 'relative',
height: 45,
width: 240,
borderRadius: 10,
backgroundColor: 'white',
marginHorizontal: 5
}}>
<Animated.View
style={{
position: 'absolute',
height: 45 - 2*2,
top: 2,
bottom: 2,
borderRadius: 10,
width: Dimensions
.get('screen').width / 3 - 3.5 ,
transform: [
{
translateX: rotationX
}
],
backgroundColor: '#d1cfcf',
}}
>
</Animated.View>
<TouchableOpacity style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}} onPress={() => {setActive(false); props.renderList() }}>
<Text>
List
</Text>
</TouchableOpacity>
<TouchableOpacity style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}} onPress={() => {setActive(true); props.renderMap() }}>
<Text>
Map
</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
export default Slider
我试过你的 expo
snack 并没有看到与动画相关的代码,所以我假设 snack 中的代码不是你当前的代码,你确实已经有了一个有效的动画, <Slider ... />
.
在您的情况下,要保持 Slider
呈现而不是卸载,您可以做的是在 render()
方法中使用变量。
基本上,您可以将
将 key
分配给特定的 JSX 也有助于指导 React 在渲染调用之间这是相同的组件,因此它也可以防止该组件的无意重新渲染。
这是对您在 post 中所写内容的评论的编辑。我希望这是有道理的。
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
whichComponentToShow: "Screen1"
};
}
goToMap = () => {
this.setState({ whichComponentToShow: "Screen2" });
};
goToList = () => {
this.setState({ whichComponentToShow: "Screen1" });
};
render() {
const { whichComponentToShow } = this.state;
/*
Keep the slider JSX in a variable to be used.
Setting a specific key also helps prevent it from being accidentally re-rendered in some conditions.
)*/
const sliderRender = <Slider key='slider' />;
if (this.state.whichComponentToShow === 'Screen1') {
return (
<View style={{ backgroundColor: '#d1cfcf', flex: 1 }}>
<ListHome
renderMap={this.goToMap.bind(this)}
renderList={this.goToList.bind(this)}
/>
{/* Put the rendered slider into the render tree */}
{sliderRender}
</View>
);
}
else if (this.state.whichComponentToShow === 'Screen2') {
return (
<View style={{ backgroundColor: '#d1cfcf', flex: 1 }}>
<MapHome
renderMap={this.goToMap.bind(this)}
renderList={this.goToList.bind(this)}
/>
{/* Put the rendered slider into the render tree */}
{sliderRender}
</View>
);
}
}
}
编辑:Expo Snack 演示其工作